acl do /login
This commit is contained in:
		
							
								
								
									
										1
									
								
								alters.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								alters.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | |||||||
|  | ALTER TABLE global_settings ADD COLUMN allowed_login_hosts TEXT; | ||||||
							
								
								
									
										47
									
								
								app.py
									
									
									
									
									
								
							
							
						
						
									
										47
									
								
								app.py
									
									
									
									
									
								
							| @@ -5,7 +5,10 @@ from werkzeug.security import generate_password_hash, check_password_hash | |||||||
| from datetime import datetime | from datetime import datetime | ||||||
| from markupsafe import Markup | from markupsafe import Markup | ||||||
| import markdown as md | import markdown as md | ||||||
| from flask import abort | from flask import request, flash, abort | ||||||
|  | import os | ||||||
|  | import re | ||||||
|  | import socket | ||||||
|  |  | ||||||
| app = Flask(__name__) | app = Flask(__name__) | ||||||
| # Ładujemy konfigurację z pliku config.py | # Ładujemy konfigurację z pliku config.py | ||||||
| @@ -52,11 +55,32 @@ class GlobalSettings(db.Model): | |||||||
|     id = db.Column(db.Integer, primary_key=True) |     id = db.Column(db.Integer, primary_key=True) | ||||||
|     numer_konta = db.Column(db.String(50), nullable=False) |     numer_konta = db.Column(db.String(50), nullable=False) | ||||||
|     numer_telefonu_blik = db.Column(db.String(50), nullable=False) |     numer_telefonu_blik = db.Column(db.String(50), nullable=False) | ||||||
|  |     allowed_login_hosts = db.Column(db.Text, nullable=True) | ||||||
|  |  | ||||||
| @login_manager.user_loader | @login_manager.user_loader | ||||||
| def load_user(user_id): | def load_user(user_id): | ||||||
|     return User.query.get(int(user_id)) |     return User.query.get(int(user_id)) | ||||||
|  |  | ||||||
|  | def is_allowed_ip(remote_ip, allowed_hosts_str): | ||||||
|  |     # Jeśli istnieje plik awaryjny, zawsze zezwalamy na dostęp | ||||||
|  |     if os.path.exists("emergency_access.txt"): | ||||||
|  |         return True | ||||||
|  |  | ||||||
|  |     # Rozdzielamy wpisy – mogą być oddzielone przecinkami lub znakami nowej linii | ||||||
|  |     allowed_hosts = re.split(r'[\n,]+', allowed_hosts_str.strip()) | ||||||
|  |     allowed_ips = set() | ||||||
|  |     for host in allowed_hosts: | ||||||
|  |         host = host.strip() | ||||||
|  |         if not host: | ||||||
|  |             continue | ||||||
|  |         try: | ||||||
|  |             # Rozwiązywanie nazwy domeny do adresu IP. | ||||||
|  |             resolved_ip = socket.gethostbyname(host) | ||||||
|  |             allowed_ips.add(resolved_ip) | ||||||
|  |         except Exception: | ||||||
|  |             # Jeśli rozwiązywanie nazwy nie powiedzie się, pomijamy ten wpis. | ||||||
|  |             continue | ||||||
|  |     return remote_ip in allowed_ips | ||||||
|  |  | ||||||
| # Dodaj filtr Markdown – pozwala na zagnieżdżanie linków i obrazków w opisie | # Dodaj filtr Markdown – pozwala na zagnieżdżanie linków i obrazków w opisie | ||||||
| @app.template_filter('markdown') | @app.template_filter('markdown') | ||||||
| @@ -86,6 +110,17 @@ def zbiorka(zbiorka_id): | |||||||
|  |  | ||||||
| @app.route('/login', methods=['GET', 'POST']) | @app.route('/login', methods=['GET', 'POST']) | ||||||
| def login(): | def login(): | ||||||
|  |     # Pobierz ustawienia globalne, w tym dozwolone hosty | ||||||
|  |     settings = GlobalSettings.query.first() | ||||||
|  |     allowed_hosts_str = "" | ||||||
|  |     if settings and settings.allowed_login_hosts: | ||||||
|  |         allowed_hosts_str = settings.allowed_login_hosts | ||||||
|  |  | ||||||
|  |     # Sprawdzenie, czy adres IP klienta jest dozwolony | ||||||
|  |     if not is_allowed_ip(request.remote_addr, allowed_hosts_str): | ||||||
|  |         flash('Dostęp do endpointu /login jest zablokowany dla Twojego adresu IP', 'danger') | ||||||
|  |         return redirect(url_for('index')) | ||||||
|  |  | ||||||
|     if request.method == 'POST': |     if request.method == 'POST': | ||||||
|         username = request.form['username'] |         username = request.form['username'] | ||||||
|         password = request.form['password'] |         password = request.form['password'] | ||||||
| @@ -99,6 +134,7 @@ def login(): | |||||||
|             flash('Nieprawidłowe dane logowania', 'danger') |             flash('Nieprawidłowe dane logowania', 'danger') | ||||||
|     return render_template('login.html') |     return render_template('login.html') | ||||||
|  |  | ||||||
|  |  | ||||||
| @app.route('/logout') | @app.route('/logout') | ||||||
| @login_required | @login_required | ||||||
| def logout(): | def logout(): | ||||||
| @@ -290,13 +326,19 @@ def admin_settings(): | |||||||
|     if request.method == 'POST': |     if request.method == 'POST': | ||||||
|          numer_konta = request.form.get('numer_konta') |          numer_konta = request.form.get('numer_konta') | ||||||
|          numer_telefonu_blik = request.form.get('numer_telefonu_blik') |          numer_telefonu_blik = request.form.get('numer_telefonu_blik') | ||||||
|  |          allowed_login_hosts = request.form.get('allowed_login_hosts') | ||||||
|           |           | ||||||
|          if settings is None: |          if settings is None: | ||||||
|              settings = GlobalSettings(numer_konta=numer_konta, numer_telefonu_blik=numer_telefonu_blik) |              settings = GlobalSettings( | ||||||
|  |                  numer_konta=numer_konta, | ||||||
|  |                  numer_telefonu_blik=numer_telefonu_blik, | ||||||
|  |                  allowed_login_hosts=allowed_login_hosts | ||||||
|  |              ) | ||||||
|              db.session.add(settings) |              db.session.add(settings) | ||||||
|          else: |          else: | ||||||
|              settings.numer_konta = numer_konta |              settings.numer_konta = numer_konta | ||||||
|              settings.numer_telefonu_blik = numer_telefonu_blik |              settings.numer_telefonu_blik = numer_telefonu_blik | ||||||
|  |              settings.allowed_login_hosts = allowed_login_hosts | ||||||
|               |               | ||||||
|          db.session.commit() |          db.session.commit() | ||||||
|          flash('Ustawienia globalne zostały zaktualizowane', 'success') |          flash('Ustawienia globalne zostały zaktualizowane', 'success') | ||||||
| @@ -304,6 +346,7 @@ def admin_settings(): | |||||||
|           |           | ||||||
|     return render_template('admin/settings.html', settings=settings) |     return render_template('admin/settings.html', settings=settings) | ||||||
|  |  | ||||||
|  |  | ||||||
| @app.route('/robots.txt') | @app.route('/robots.txt') | ||||||
| def robots(): | def robots(): | ||||||
|     if app.config.get("BLOCK_BOTS", False): |     if app.config.get("BLOCK_BOTS", False): | ||||||
|   | |||||||
							
								
								
									
										3
									
								
								emergency_access
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								emergency_access
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | |||||||
|  | Jeśli ten plik istwnieje w katalogu apliakcji, to wylacza zebzpieczenie logowania do panelu admina z ograniczeniem IP. | ||||||
|  |  | ||||||
|  | Musi miec rozszerzenie .txt | ||||||
| @@ -16,6 +16,10 @@ | |||||||
|               <label for="numer_telefonu_blik" class="form-label">Globalny numer telefonu BLIK</label> |               <label for="numer_telefonu_blik" class="form-label">Globalny numer telefonu BLIK</label> | ||||||
|               <input type="text" class="form-control" id="numer_telefonu_blik" name="numer_telefonu_blik" value="{{ settings.numer_telefonu_blik if settings else '' }}" required> |               <input type="text" class="form-control" id="numer_telefonu_blik" name="numer_telefonu_blik" value="{{ settings.numer_telefonu_blik if settings else '' }}" required> | ||||||
|           </div> |           </div> | ||||||
|  |           <div class="mb-3"> | ||||||
|  |               <label for="allowed_login_hosts" class="form-label">Dozwolone hosty logowania</label> | ||||||
|  |               <textarea class="form-control" id="allowed_login_hosts" name="allowed_login_hosts" rows="4" placeholder="Podaj adresy IP lub nazwy domen oddzielone przecinkami lub nowymi liniami">{{ settings.allowed_login_hosts if settings and settings.allowed_login_hosts else '' }}</textarea> | ||||||
|  |           </div> | ||||||
|           <button type="submit" class="btn btn-primary">Zapisz ustawienia</button> |           <button type="submit" class="btn btn-primary">Zapisz ustawienia</button> | ||||||
|           <a href="{{ url_for('admin_dashboard') }}" class="btn btn-secondary">Powrót</a> |           <a href="{{ url_for('admin_dashboard') }}" class="btn btn-secondary">Powrót</a> | ||||||
|       </form> |       </form> | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Mateusz Gruszczyński
					Mateusz Gruszczyński