danmia
This commit is contained in:
5
.env
Normal file
5
.env
Normal file
@@ -0,0 +1,5 @@
|
||||
# .env
|
||||
FLASK_ENV=production
|
||||
DOMAIN=http.pathl.pl
|
||||
PROD_PORT=8000
|
||||
SECRET_KEY=THE_PAsswd+key
|
||||
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
venv/
|
||||
.idea/
|
||||
BIN
__pycache__/http.cpython-313.pyc
Normal file
BIN
__pycache__/http.cpython-313.pyc
Normal file
Binary file not shown.
BIN
__pycache__/utils.cpython-313.pyc
Normal file
BIN
__pycache__/utils.cpython-313.pyc
Normal file
Binary file not shown.
181
app.py
Normal file
181
app.py
Normal file
@@ -0,0 +1,181 @@
|
||||
from flask import Flask, render_template, request, jsonify, redirect, url_for, session
|
||||
from utils import (
|
||||
user_add, is_person, verify_password,
|
||||
get_user_data, get_all_users, delete_user
|
||||
)
|
||||
import json
|
||||
|
||||
app = Flask(__name__)
|
||||
app.secret_key = 'twoj_sekretny_klucz_zmien_to_w_produkcji' # Potrzebne dla sesji
|
||||
|
||||
|
||||
@app.route('/')
|
||||
def root():
|
||||
return render_template('index.html')
|
||||
|
||||
|
||||
@app.route('/register', methods=['GET', 'POST'])
|
||||
def register():
|
||||
if request.method == 'POST':
|
||||
name = request.form.get('username')
|
||||
password = request.form.get('password')
|
||||
confirm_password = request.form.get('confirm_password')
|
||||
|
||||
# Walidacja
|
||||
if not name or not password:
|
||||
return "Wszystkie pola są wymagane!", 400
|
||||
|
||||
if password != confirm_password:
|
||||
return "Hasła nie są identyczne!", 400
|
||||
|
||||
if len(password) < 4:
|
||||
return "Hasło musi mieć co najmniej 4 znaki!", 400
|
||||
|
||||
if is_person(name):
|
||||
return "Użytkownik już istnieje!", 400
|
||||
|
||||
# Dodaj użytkownika
|
||||
user_add(name, password)
|
||||
return redirect(url_for('login'))
|
||||
|
||||
return render_template('register.html')
|
||||
|
||||
|
||||
@app.route('/login', methods=['GET', 'POST'])
|
||||
def login():
|
||||
if request.method == 'POST':
|
||||
name = request.form.get('username')
|
||||
password = request.form.get('password')
|
||||
|
||||
if not name or not password:
|
||||
return "Wszystkie pola są wymagane!", 400
|
||||
|
||||
if not is_person(name):
|
||||
return "Użytkownik nie istnieje!", 404
|
||||
|
||||
if verify_password(name, password):
|
||||
# Zapisz w sesji że użytkownik jest zalogowany
|
||||
session['username'] = name
|
||||
return redirect(url_for('dashboard'))
|
||||
else:
|
||||
return "Złe hasło!", 401
|
||||
|
||||
return render_template('login.html')
|
||||
|
||||
|
||||
@app.route('/dashboard')
|
||||
def dashboard():
|
||||
# Sprawdź czy użytkownik jest zalogowany
|
||||
if 'username' not in session:
|
||||
return redirect(url_for('login'))
|
||||
|
||||
user_data = get_user_data(session['username'])
|
||||
return render_template('dashboard.html', user=user_data)
|
||||
|
||||
|
||||
@app.route('/logout')
|
||||
def logout():
|
||||
session.pop('username', None)
|
||||
return redirect(url_for('root'))
|
||||
|
||||
|
||||
@app.route('/api/passwd/<name>', methods=['GET'])
|
||||
def api_get_password(name):
|
||||
"""API endpoint do pobierania hasła (tylko JSON)"""
|
||||
if not is_person(name):
|
||||
return jsonify({"error": "Brak osoby"}), 404
|
||||
|
||||
user_data = get_user_data(name)
|
||||
if user_data:
|
||||
return jsonify({
|
||||
"user": user_data["user"],
|
||||
"password": user_data["password"],
|
||||
"status": "success"
|
||||
})
|
||||
else:
|
||||
return jsonify({"error": "Brak hasła"}), 404
|
||||
|
||||
|
||||
@app.route('/api/users', methods=['GET'])
|
||||
def api_get_all_users():
|
||||
"""API endpoint do pobierania wszystkich użytkowników"""
|
||||
users = get_all_users()
|
||||
return jsonify({
|
||||
"count": len(users),
|
||||
"users": users
|
||||
})
|
||||
|
||||
|
||||
@app.route('/api/check/<name>', methods=['GET'])
|
||||
def api_check_user(name):
|
||||
"""API endpoint do sprawdzania czy użytkownik istnieje"""
|
||||
exists = is_person(name)
|
||||
return jsonify({
|
||||
"user": name,
|
||||
"exists": bool(exists),
|
||||
"code": exists
|
||||
})
|
||||
|
||||
|
||||
@app.route('/api/register', methods=['POST'])
|
||||
def api_register():
|
||||
"""API endpoint do rejestracji (JSON)"""
|
||||
data = request.get_json()
|
||||
|
||||
if not data:
|
||||
return jsonify({"error": "Brak danych JSON"}), 400
|
||||
|
||||
name = data.get('username')
|
||||
password = data.get('password')
|
||||
|
||||
if not name or not password:
|
||||
return jsonify({"error": "Username i password są wymagane"}), 400
|
||||
|
||||
if is_person(name):
|
||||
return jsonify({"error": "Użytkownik już istnieje"}), 409
|
||||
|
||||
user_add(name, password)
|
||||
return jsonify({"message": f"Użytkownik {name} zarejestrowany"}), 201
|
||||
|
||||
|
||||
@app.route('/api/login', methods=['POST'])
|
||||
def api_login():
|
||||
"""API endpoint do logowania (JSON)"""
|
||||
data = request.get_json()
|
||||
|
||||
if not data:
|
||||
return jsonify({"error": "Brak danych JSON"}), 400
|
||||
|
||||
name = data.get('username')
|
||||
password = data.get('password')
|
||||
|
||||
if not name or not password:
|
||||
return jsonify({"error": "Username i password są wymagane"}), 400
|
||||
|
||||
if not is_person(name):
|
||||
return jsonify({"error": "Użytkownik nie istnieje"}), 404
|
||||
|
||||
if verify_password(name, password):
|
||||
return jsonify({
|
||||
"message": "Zalogowano pomyślnie",
|
||||
"user": name,
|
||||
"status": "success"
|
||||
})
|
||||
else:
|
||||
return jsonify({"error": "Złe hasło"}), 401
|
||||
|
||||
|
||||
@app.route('/debug/users')
|
||||
def debug_users():
|
||||
"""Debug endpoint - pokazuje wszystkich użytkowników"""
|
||||
if 'username' not in session:
|
||||
return redirect(url_for('login'))
|
||||
|
||||
users = get_all_users()
|
||||
return jsonify(users)
|
||||
|
||||
@app.route("/css/")
|
||||
def css():
|
||||
return render_template("index_css.html")
|
||||
if __name__ == '__main__':
|
||||
app.run(port=2500)
|
||||
8
file.json
Normal file
8
file.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"users": [
|
||||
{
|
||||
"user": "neon",
|
||||
"password": "1234"
|
||||
}
|
||||
]
|
||||
}
|
||||
284
makefile
Normal file
284
makefile
Normal file
@@ -0,0 +1,284 @@
|
||||
# Zmienne
|
||||
PYTHON = venv/bin/python
|
||||
PIP = venv/bin/pip
|
||||
FLASK = venv/bin/flask
|
||||
APP = app.py
|
||||
PORT = 2500
|
||||
PROD_PORT = 8000
|
||||
DOMAIN = http.pathl.pl
|
||||
PROJECT_DIR = /home/neon/PycharmProjects/http
|
||||
VENV_DIR = $(PROJECT_DIR)/venv
|
||||
|
||||
# Kolory do outputu
|
||||
GREEN = \033[0;32m
|
||||
RED = \033[0;31m
|
||||
YELLOW = \033[1;33m
|
||||
BLUE = \033[0;34m
|
||||
NC = \033[0m # No Color
|
||||
|
||||
.PHONY: help setup venv install run debug clean test api status kill reset release prod-start prod-stop prod-restart prod-status init-db backup
|
||||
|
||||
help:
|
||||
@echo "$(GREEN)Dostępne komendy:$(NC)"
|
||||
@echo ""
|
||||
@echo "$(BLUE)=== Rozwój (Development) ===$(NC)"
|
||||
@echo " make setup - Przygotowanie środowiska (venv + zależności)"
|
||||
@echo " make venv - Tworzenie środowiska wirtualnego"
|
||||
@echo " make install - Instalacja zależności"
|
||||
@echo " make debug - Uruchomienie serwera w trybie debug (port $(PORT))"
|
||||
@echo " make run - Uruchomienie serwera (standardowo)"
|
||||
@echo ""
|
||||
@echo "$(BLUE)=== Produkcja (Production) ===$(NC)"
|
||||
@echo " make release - Pełne wdrożenie produkcyjne (budowa + start)"
|
||||
@echo " make prod-start - Uruchomienie serwera produkcyjnego (Gunicorn)"
|
||||
@echo " make prod-stop - Zatrzymanie serwera produkcyjnego"
|
||||
@echo " make prod-restart - Restart serwera produkcyjnego"
|
||||
@echo " make prod-status - Status serwera produkcyjnego"
|
||||
@echo ""
|
||||
@echo "$(BLUE)=== Narzędzia ===$(NC)"
|
||||
@echo " make clean - Usunięcie plików tymczasowych"
|
||||
@echo " make test - Testowanie API"
|
||||
@echo " make api - Pokazuje endpointy API"
|
||||
@echo " make status - Sprawdza status serwera deweloperskiego"
|
||||
@echo " make kill - Zabija proces Flask na porcie $(PORT)"
|
||||
@echo " make reset - Resetuje bazę danych (usuwa file.json)"
|
||||
@echo " make backup - Backup bazy danych"
|
||||
@echo " make logs - Podgląd logów produkcyjnych"
|
||||
|
||||
# ==================== DEVELOPMENT ====================
|
||||
|
||||
setup: venv install
|
||||
@echo "$(GREEN)✓ Środowisko gotowe!$(NC)"
|
||||
@echo "Uruchom: make debug"
|
||||
|
||||
venv:
|
||||
@echo "$(GREEN)Tworzenie środowiska wirtualnego...$(NC)"
|
||||
@python3 -m venv venv || python -m venv venv
|
||||
@echo "$(GREEN)✓ Środowisko utworzone$(NC)"
|
||||
|
||||
install:
|
||||
@echo "$(GREEN)Instalacja zależności...$(NC)"
|
||||
@$(PIP) install --upgrade pip
|
||||
@$(PIP) install flask
|
||||
@$(PIP) install flask-cors
|
||||
@$(PIP) install gunicorn
|
||||
@$(PIP) install python-dotenv
|
||||
@echo "$(GREEN)✓ Zależności zainstalowane$(NC)"
|
||||
@# Tworzenie requirements.txt
|
||||
@$(PIP) freeze > requirements.txt 2>/dev/null || true
|
||||
|
||||
run:
|
||||
@echo "$(GREEN)Uruchamianie serwera na porcie $(PORT)...$(NC)"
|
||||
@$(PYTHON) $(APP)
|
||||
|
||||
debug:
|
||||
@echo "$(GREEN)Uruchamianie serwera w trybie DEBUG na porcie $(PORT)...$(NC)"
|
||||
@export FLASK_ENV=development FLASK_DEBUG=1 && $(PYTHON) $(APP)
|
||||
|
||||
clean:
|
||||
@echo "$(GREEN)Czyszczenie plików tymczasowych...$(NC)"
|
||||
@find . -type d -name "__pycache__" -exec rm -rf {} + 2>/dev/null || true
|
||||
@find . -type f -name "*.pyc" -delete 2>/dev/null || true
|
||||
@find . -type f -name "*.pyo" -delete 2>/dev/null || true
|
||||
@rm -rf .pytest_cache 2>/dev/null || true
|
||||
@echo "$(GREEN)✓ Pliki tymczasowe usunięte$(NC)"
|
||||
|
||||
# ==================== PRODUCTION ====================
|
||||
|
||||
release: clean install prod-stop prod-start prod-status
|
||||
@echo "$(GREEN)========================================$(NC)"
|
||||
@echo "$(GREEN)✓ Wdrożenie produkcyjne zakończone!$(NC)"
|
||||
@echo "$(GREEN)========================================$(NC)"
|
||||
@echo "Aplikacja dostępna pod adresem: http://$(DOMAIN)"
|
||||
@echo "Port: $(PROD_PORT)"
|
||||
@echo ""
|
||||
@echo "Aby sprawdzić status: make prod-status"
|
||||
@echo "Aby zatrzymać: make prod-stop"
|
||||
@echo "Aby zobaczyć logi: make logs"
|
||||
|
||||
prod-start:
|
||||
@echo "$(GREEN)Uruchamianie serwera produkcyjnego...$(NC)"
|
||||
@echo "Domena: http://$(DOMAIN)"
|
||||
@echo "Port: $(PROD_PORT)"
|
||||
@# Zabij stary proces jeśli istnieje
|
||||
@-lsof -ti :$(PROD_PORT) | xargs kill -9 2>/dev/null || true
|
||||
@# Uruchom Gunicorn w tle
|
||||
@cd $(PROJECT_DIR) && nohup $(VENV_DIR)/bin/gunicorn -w 4 -b 0.0.0.0:$(PROD_PORT) app:app > logs/production.log 2>&1 &
|
||||
@sleep 2
|
||||
@echo "$(GREEN)✓ Serwer produkcyjny uruchomiony!$(NC)"
|
||||
@echo "PID: $$(lsof -ti :$(PROD_PORT) 2>/dev/null || echo 'Nie można odczytać')"
|
||||
@echo "Logi: $(PROJECT_DIR)/logs/production.log"
|
||||
|
||||
prod-stop:
|
||||
@echo "$(RED)Zatrzymywanie serwera produkcyjnego...$(NC)"
|
||||
@-lsof -ti :$(PROD_PORT) | xargs kill -9 2>/dev/null && echo "$(GREEN)✓ Serwer zatrzymany$(NC)" || echo "Serwer nie był uruchomiony"
|
||||
@-pkill -f "gunicorn.*app:app" 2>/dev/null || true
|
||||
|
||||
prod-restart: prod-stop prod-start
|
||||
@echo "$(GREEN)✓ Serwer produkcyjny zrestartowany$(NC)"
|
||||
|
||||
prod-status:
|
||||
@echo "$(BLUE)Status serwera produkcyjnego:$(NC)"
|
||||
@if lsof -i :$(PROD_PORT) > /dev/null 2>&1; then \
|
||||
echo "$(GREEN)✓ Serwer DZIAŁA na porcie $(PROD_PORT)$(NC)"; \
|
||||
echo "Domena: http://$(DOMAIN)"; \
|
||||
echo "PID: $$(lsof -ti :$(PROD_PORT))"; \
|
||||
echo ""; \
|
||||
echo "Test połączenia:"; \
|
||||
curl -s -o /dev/null -w "Status HTTP: %{http_code}\n" http://localhost:$(PROD_PORT)/; \
|
||||
else \
|
||||
echo "$(RED)✗ Serwer NIE działa na porcie $(PROD_PORT)$(NC)"; \
|
||||
fi
|
||||
|
||||
# ==================== UTILS ====================
|
||||
|
||||
test:
|
||||
@echo "$(GREEN)Testowanie API (dev:$(PORT), prod:$(PROD_PORT))...$(NC)"
|
||||
@echo "$(YELLOW)1. Test root endpoint (dev):$(NC)"
|
||||
@curl -s http://localhost:$(PORT)/ 2>/dev/null | head -c 200 || echo "Serwer dev nie uruchomiony"
|
||||
@echo "\n$(YELLOW)2. Test API check user (prod):$(NC)"
|
||||
@curl -s http://localhost:$(PROD_PORT)/api/check/admin 2>/dev/null || echo "Serwer prod nie uruchomiony"
|
||||
@echo "\n$(YELLOW)3. Test API get users (prod):$(NC)"
|
||||
@curl -s http://localhost:$(PROD_PORT)/api/users 2>/dev/null || echo "Serwer prod nie uruchomiony"
|
||||
@echo ""
|
||||
|
||||
api:
|
||||
@echo "$(GREEN)Dostępne endpointy API:$(NC)"
|
||||
@echo ""
|
||||
@echo "$(BLUE)Deweloperskie (http://localhost:$(PORT)):$(NC)"
|
||||
@echo " GET / - Strona główna"
|
||||
@echo " GET /register - Formularz rejestracji"
|
||||
@echo " POST /register - Rejestracja użytkownika"
|
||||
@echo " GET /login - Formularz logowania"
|
||||
@echo " POST /login - Logowanie"
|
||||
@echo " GET /dashboard - Panel użytkownika"
|
||||
@echo " GET /logout - Wylogowanie"
|
||||
@echo ""
|
||||
@echo "$(BLUE)Produkcyjne (http://$(DOMAIN)):$(NC)"
|
||||
@echo " GET /api/users - Lista wszystkich użytkowników"
|
||||
@echo " GET /api/passwd/<name> - Pobierz hasło użytkownika"
|
||||
@echo " GET /api/check/<name> - Sprawdź czy użytkownik istnieje"
|
||||
@echo " POST /api/register - Rejestracja przez API (JSON)"
|
||||
@echo " POST /api/login - Logowanie przez API (JSON)"
|
||||
@echo ""
|
||||
@echo "$(GREEN)Przykłady użycia API (produkcja):$(NC)"
|
||||
@echo " curl -X POST http://$(DOMAIN)/api/register \\"
|
||||
@echo " -H \"Content-Type: application/json\" \\"
|
||||
@echo " -d '{\"username\":\"test\",\"password\":\"123\"}'"
|
||||
@echo ""
|
||||
@echo " curl http://$(DOMAIN)/api/check/test"
|
||||
@echo " curl http://$(DOMAIN)/api/users"
|
||||
|
||||
status:
|
||||
@echo "$(GREEN)Sprawdzanie statusu serwerów:$(NC)"
|
||||
@echo ""
|
||||
@echo "$(BLUE)Development (port $(PORT)):$(NC)"
|
||||
@if lsof -i :$(PORT) > /dev/null 2>&1; then \
|
||||
echo " $(GREEN)✓ Działa$(NC) - PID: $$(lsof -ti :$(PORT))"; \
|
||||
else \
|
||||
echo " $(RED)✗ Nie działa$(NC)"; \
|
||||
fi
|
||||
@echo ""
|
||||
@echo "$(BLUE)Production (port $(PROD_PORT)):$(NC)"
|
||||
@if lsof -i :$(PROD_PORT) > /dev/null 2>&1; then \
|
||||
echo " $(GREEN)✓ Działa$(NC) - PID: $$(lsof -ti :$(PROD_PORT))"; \
|
||||
echo " URL: http://$(DOMAIN)"; \
|
||||
else \
|
||||
echo " $(RED)✗ Nie działa$(NC)"; \
|
||||
fi
|
||||
|
||||
kill:
|
||||
@echo "$(RED)Zabijanie procesu deweloperskiego na porcie $(PORT)...$(NC)"
|
||||
@lsof -ti :$(PORT) | xargs kill -9 2>/dev/null || echo "Brak procesu na porcie $(PORT)"
|
||||
@echo "$(GREEN)✓ Proces deweloperski zabity$(NC)"
|
||||
|
||||
reset:
|
||||
@echo "$(RED)Resetowanie bazy danych...$(NC)"
|
||||
@rm -f file.json
|
||||
@echo "{}" > file.json
|
||||
@echo "$(GREEN)✓ Baza danych zresetowana (file.json)$(NC)"
|
||||
|
||||
backup:
|
||||
@echo "$(GREEN)Tworzenie backupu bazy danych...$(NC)"
|
||||
@if [ -f file.json ]; then \
|
||||
cp file.json file.json.backup.$$(date +%Y%m%d_%H%M%S); \
|
||||
echo "$(GREEN)✓ Backup utworzony$(NC)"; \
|
||||
else \
|
||||
echo "$(YELLOW)Brak bazy danych do backupu$(NC)"; \
|
||||
fi
|
||||
|
||||
logs:
|
||||
@echo "$(GREEN)Logi produkcyjne (Ctrl+C aby zakończyć):$(NC)"
|
||||
@mkdir -p logs
|
||||
@tail -f logs/production.log 2>/dev/null || echo "Brak logów - uruchom najpierw make prod-start"
|
||||
|
||||
init-db:
|
||||
@echo "$(GREEN)Inicjalizacja bazy danych...$(NC)"
|
||||
@if [ ! -f file.json ]; then \
|
||||
echo '{"users": []}' > file.json; \
|
||||
echo "$(GREEN)✓ Utworzono nową bazę danych$(NC)"; \
|
||||
else \
|
||||
echo "$(YELLOW)Baza danych już istnieje$(NC)"; \
|
||||
fi
|
||||
|
||||
# ==================== PRODUCTION SETUP ====================
|
||||
|
||||
prod-setup: clean install init-db
|
||||
@echo "$(GREEN)✓ Środowisko produkcyjne gotowe$(NC)"
|
||||
@mkdir -p logs
|
||||
@echo "Uruchom: make release"
|
||||
|
||||
# ==================== DLA SYSTEMD (autostart) ====================
|
||||
|
||||
install-service:
|
||||
@echo "$(GREEN)Instalacja usługi systemd...$(NC)"
|
||||
@sudo bash -c 'cat > /etc/systemd/system/http-api.service << EOF
|
||||
[Unit]
|
||||
Description=HTTP API Flask App
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
User=$(shell whoami)
|
||||
WorkingDirectory=$(PROJECT_DIR)
|
||||
ExecStart=$(VENV_DIR)/bin/gunicorn -w 4 -b 0.0.0.0:$(PROD_PORT) app:app
|
||||
Restart=always
|
||||
RestartSec=10
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF'
|
||||
@sudo systemctl daemon-reload
|
||||
@echo "$(GREEN)✓ Usługa zainstalowana$(NC)"
|
||||
@echo "Uruchom: sudo systemctl start http-api"
|
||||
@echo "Włącz autostart: sudo systemctl enable http-api"
|
||||
|
||||
remove-service:
|
||||
@echo "$(RED)Usuwanie usługi systemd...$(NC)"
|
||||
@sudo systemctl stop http-api 2>/dev/null || true
|
||||
@sudo systemctl disable http-api 2>/dev/null || true
|
||||
@sudo rm -f /etc/systemd/system/http-api.service
|
||||
@sudo systemctl daemon-reload
|
||||
@echo "$(GREEN)✓ Usługa usunięta$(NC)"
|
||||
|
||||
# ==================== DLA NGINX (proxy) ====================
|
||||
|
||||
setup-nginx:
|
||||
@echo "$(GREEN)Konfiguracja Nginx jako reverse proxy...$(NC)"
|
||||
@sudo bash -c 'cat > /etc/nginx/sites-available/http-api << EOF
|
||||
server {
|
||||
listen 80;
|
||||
server_name $(DOMAIN);
|
||||
|
||||
location / {
|
||||
proxy_pass http://127.0.0.1:$(PROD_PORT);
|
||||
proxy_set_header Host $$host;
|
||||
proxy_set_header X-Real-IP $$remote_addr;
|
||||
proxy_set_header X-Forwarded-For $$proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $$scheme;
|
||||
}
|
||||
}
|
||||
EOF'
|
||||
@sudo ln -sf /etc/nginx/sites-available/http-api /etc/nginx/sites-enabled/
|
||||
@sudo nginx -t && sudo systemctl reload nginx
|
||||
@echo "$(GREEN)✓ Nginx skonfigurowany$(NC)"
|
||||
@echo "Domena: http://$(DOMAIN)"
|
||||
29
templates/dashboard.html
Normal file
29
templates/dashboard.html
Normal file
@@ -0,0 +1,29 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="pl">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Panel użytkownika</title>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<h1>Witaj, {{ user.user }}!</h1>
|
||||
<div class="info">
|
||||
<p><strong>Zalogowany jako:</strong> {{ user.user }}</p>
|
||||
<p><strong>Twoje hasło:</strong> {{ user.password }}</p>
|
||||
</div>
|
||||
|
||||
<a href="/logout" class="logout">Wyloguj się</a>
|
||||
|
||||
<div class="api-info">
|
||||
<h3>Informacje API:</h3>
|
||||
<p>GET /api/users - lista wszystkich użytkowników</p>
|
||||
<p>GET /api/passwd/<nazwa> - pobierz hasło użytkownika</p>
|
||||
<p>GET /api/check/<nazwa> - sprawdź czy użytkownik istnieje</p>
|
||||
<p>Zobacz stronę z CSS:</p>
|
||||
<a href="/css/">Kliknij tutaj, aby przejść</a>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
19
templates/index.html
Normal file
19
templates/index.html
Normal file
@@ -0,0 +1,19 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="pl">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Strona Główna</title>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<h1>Witaj na naszej stronie!</h1>
|
||||
<p>System rejestracji i logowania użytkowników</p>
|
||||
<div class="buttons">
|
||||
<a href="/register" class="btn btn-primary">Rejestracja</a>
|
||||
<a href="/login" class="btn btn-secondary">Logowanie</a>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
45
templates/index_css.html
Normal file
45
templates/index_css.html
Normal file
@@ -0,0 +1,45 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="pl">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Prosta strona z CSS</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: Arial, sans-serif;
|
||||
background-color: #f0f8ff;
|
||||
color: #333;
|
||||
text-align: center;
|
||||
padding: 50px;
|
||||
}
|
||||
|
||||
h1 {
|
||||
color: #2c3e50;
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.button {
|
||||
display: inline-block;
|
||||
padding: 10px 20px;
|
||||
margin-top: 20px;
|
||||
font-size: 16px;
|
||||
color: #fff;
|
||||
background-color: #3498db;
|
||||
border: none;
|
||||
border-radius: 5px;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.button:hover {
|
||||
background-color: #2980b9;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Witaj na mojej prostej stronie!</h1>
|
||||
<p>To jest przykładowa strona HTML z prostym CSS.</p>
|
||||
<a href="/" class="button">Powrót do strony głównej</a>
|
||||
</body>
|
||||
</html>
|
||||
22
templates/login.html
Normal file
22
templates/login.html
Normal file
@@ -0,0 +1,22 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="pl">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Logowanie</title>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<h1>Logowanie</h1>
|
||||
<form method="POST">
|
||||
<input type="text" name="username" placeholder="Nazwa użytkownika" required>
|
||||
<input type="password" name="password" placeholder="Hasło" required>
|
||||
<button type="submit">Zaloguj</button>
|
||||
</form>
|
||||
<div class="link">
|
||||
<a href="/register">Nie masz konta? Zarejestruj się</a>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
23
templates/register.html
Normal file
23
templates/register.html
Normal file
@@ -0,0 +1,23 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="pl">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Rejestracja</title>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<h1>Rejestracja</h1>
|
||||
<form method="POST">
|
||||
<input type="text" name="username" placeholder="Nazwa użytkownika" required>
|
||||
<input type="password" name="password" placeholder="Hasło" required>
|
||||
<input type="password" name="confirm_password" placeholder="Potwierdź hasło" required>
|
||||
<button type="submit">Zarejestruj</button>
|
||||
</form>
|
||||
<div class="link">
|
||||
<a href="/login">Masz już konto? Zaloguj się</a>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
118
utils.py
Normal file
118
utils.py
Normal file
@@ -0,0 +1,118 @@
|
||||
import json
|
||||
import os
|
||||
|
||||
|
||||
def user_add(new_user, new_password):
|
||||
"""Dodaje nowego użytkownika lub aktualizuje hasło"""
|
||||
file_path = "file.json"
|
||||
|
||||
# Wczytanie pliku JSON
|
||||
if os.path.exists(file_path):
|
||||
with open(file_path, "r") as f:
|
||||
try:
|
||||
data = json.load(f)
|
||||
except json.JSONDecodeError:
|
||||
data = {"users": []}
|
||||
else:
|
||||
data = {"users": []}
|
||||
|
||||
# Sprawdź czy użytkownik już istnieje
|
||||
for entry in data["users"]:
|
||||
if entry.get("user") == new_user:
|
||||
# Aktualizuj hasło
|
||||
entry["password"] = new_password
|
||||
with open(file_path, "w") as f:
|
||||
json.dump(data, f, indent=4)
|
||||
return False # Zaktualizowano
|
||||
|
||||
# Dodaj nowego użytkownika
|
||||
new_entry = {"user": new_user, "password": new_password}
|
||||
data["users"].append(new_entry)
|
||||
|
||||
# Zapis do pliku JSON
|
||||
with open(file_path, "w") as f:
|
||||
json.dump(data, f, indent=4)
|
||||
return True # Dodano nowego
|
||||
|
||||
|
||||
def is_person(user_to_find):
|
||||
"""Sprawdza czy użytkownik istnieje - zwraca 1 lub 0"""
|
||||
file_path = "file.json"
|
||||
|
||||
try:
|
||||
with open(file_path, "r") as f:
|
||||
data = json.load(f)
|
||||
except (FileNotFoundError, json.JSONDecodeError):
|
||||
return 0
|
||||
|
||||
for entry in data.get("users", []):
|
||||
if entry.get("user") == user_to_find:
|
||||
return 1
|
||||
return 0
|
||||
|
||||
|
||||
def verify_password(user_to_check, password_to_check):
|
||||
"""Sprawdza hasło bez usuwania użytkownika"""
|
||||
file_path = "file.json"
|
||||
|
||||
try:
|
||||
with open(file_path, "r") as f:
|
||||
data = json.load(f)
|
||||
except (FileNotFoundError, json.JSONDecodeError):
|
||||
return False
|
||||
|
||||
for entry in data.get("users", []):
|
||||
if entry.get("user") == user_to_check:
|
||||
return entry.get("password") == password_to_check
|
||||
|
||||
return False
|
||||
|
||||
|
||||
def get_user_data(user_to_find):
|
||||
"""Pobiera dane użytkownika bez usuwania"""
|
||||
file_path = "file.json"
|
||||
|
||||
try:
|
||||
with open(file_path, "r") as f:
|
||||
data = json.load(f)
|
||||
except (FileNotFoundError, json.JSONDecodeError):
|
||||
return None
|
||||
|
||||
for entry in data.get("users", []):
|
||||
if entry.get("user") == user_to_find:
|
||||
return {"user": entry["user"], "password": entry["password"]}
|
||||
|
||||
return None
|
||||
|
||||
|
||||
def get_all_users():
|
||||
"""Zwraca listę wszystkich użytkowników"""
|
||||
file_path = "file.json"
|
||||
|
||||
try:
|
||||
with open(file_path, "r") as f:
|
||||
data = json.load(f)
|
||||
except (FileNotFoundError, json.JSONDecodeError):
|
||||
return []
|
||||
|
||||
return data.get("users", [])
|
||||
|
||||
|
||||
def delete_user(user_to_delete):
|
||||
"""Usuwa użytkownika z bazy"""
|
||||
file_path = "file.json"
|
||||
|
||||
try:
|
||||
with open(file_path, "r") as f:
|
||||
data = json.load(f)
|
||||
except (FileNotFoundError, json.JSONDecodeError):
|
||||
return False
|
||||
|
||||
for i, entry in enumerate(data.get("users", [])):
|
||||
if entry.get("user") == user_to_delete:
|
||||
data["users"].pop(i)
|
||||
with open(file_path, "w") as f:
|
||||
json.dump(data, f, indent=4)
|
||||
return True
|
||||
|
||||
return False
|
||||
Reference in New Issue
Block a user