deutsche Zeit statt UTC
Dieser Commit ist enthalten in:
@@ -48,7 +48,8 @@
|
|||||||
"Bash(find:*)",
|
"Bash(find:*)",
|
||||||
"Bash(openssl x509:*)",
|
"Bash(openssl x509:*)",
|
||||||
"Bash(cat:*)",
|
"Bash(cat:*)",
|
||||||
"Bash(openssl dhparam:*)"
|
"Bash(openssl dhparam:*)",
|
||||||
|
"Bash(rg:*)"
|
||||||
],
|
],
|
||||||
"deny": []
|
"deny": []
|
||||||
}
|
}
|
||||||
|
|||||||
81
JOURNAL.md
81
JOURNAL.md
@@ -1211,3 +1211,84 @@ Die Session-Daten werden erst gefüllt, wenn der License Server API implementier
|
|||||||
- ✅ CAPTCHA wird nur angezeigt wenn Keys konfiguriert sind
|
- ✅ CAPTCHA wird nur angezeigt wenn Keys konfiguriert sind
|
||||||
- ✅ Für PoC-Phase ohne CAPTCHA nutzbar
|
- ✅ Für PoC-Phase ohne CAPTCHA nutzbar
|
||||||
- ✅ Produktiv-ready wenn CAPTCHA-Keys eingetragen werden
|
- ✅ Produktiv-ready wenn CAPTCHA-Keys eingetragen werden
|
||||||
|
|
||||||
|
### 2025-06-08: Zeitzone auf Europe/Berlin umgestellt
|
||||||
|
|
||||||
|
**Problem:**
|
||||||
|
- Alle Zeitstempel wurden in UTC gespeichert und angezeigt
|
||||||
|
- Backup-Dateinamen zeigten UTC-Zeit statt deutsche Zeit
|
||||||
|
- Verwirrung bei Zeitangaben im Admin Panel und Logs
|
||||||
|
|
||||||
|
**Lösung:**
|
||||||
|
1. **Docker Container Zeitzone konfiguriert:**
|
||||||
|
- Alle Dockerfiles mit `TZ=Europe/Berlin` und tzdata Installation
|
||||||
|
- PostgreSQL mit `PGTZ=Europe/Berlin` für Datenbank-Zeitzone
|
||||||
|
- Explizite Zeitzone-Dateien in /etc/localtime und /etc/timezone
|
||||||
|
|
||||||
|
2. **Python Code angepasst:**
|
||||||
|
- Import von `zoneinfo.ZoneInfo` für Zeitzonenunterstützung
|
||||||
|
- Alle `datetime.now()` Aufrufe mit `ZoneInfo("Europe/Berlin")`
|
||||||
|
- `.replace(tzinfo=None)` für Kompatibilität mit timezone-unaware Timestamps
|
||||||
|
|
||||||
|
3. **PostgreSQL Konfiguration:**
|
||||||
|
- `SET timezone = 'Europe/Berlin';` in init.sql
|
||||||
|
- Umgebungsvariablen TZ und PGTZ in docker-compose.yaml
|
||||||
|
|
||||||
|
4. **docker-compose.yaml erweitert:**
|
||||||
|
- `TZ: Europe/Berlin` für alle Services
|
||||||
|
|
||||||
|
**Geänderte Dateien:**
|
||||||
|
- `v2_adminpanel/Dockerfile`: Zeitzone und tzdata hinzugefügt
|
||||||
|
- `v2_postgres/Dockerfile`: Zeitzone und tzdata hinzugefügt
|
||||||
|
- `v2_nginx/Dockerfile`: Zeitzone und tzdata hinzugefügt
|
||||||
|
- `v2_lizenzserver/Dockerfile`: Zeitzone und tzdata hinzugefügt
|
||||||
|
- `v2_adminpanel/app.py`: 14 datetime.now() Aufrufe mit Zeitzone versehen
|
||||||
|
- `v2_adminpanel/init.sql`: PostgreSQL Zeitzone gesetzt
|
||||||
|
- `v2/docker-compose.yaml`: TZ Environment-Variable für alle Services
|
||||||
|
|
||||||
|
**Ergebnis:**
|
||||||
|
- ✅ Alle neuen Zeitstempel werden in deutscher Zeit (Europe/Berlin) gespeichert
|
||||||
|
- ✅ Backup-Dateinamen zeigen korrekte deutsche Zeit
|
||||||
|
- ✅ Admin Panel zeigt alle Zeiten in deutscher Zeitzone
|
||||||
|
- ✅ Automatische Anpassung bei Sommer-/Winterzeit
|
||||||
|
- ✅ Konsistente Zeitangaben über alle Komponenten
|
||||||
|
|
||||||
|
**Hinweis:** Nach diesen Änderungen müssen die Docker Container neu gebaut werden:
|
||||||
|
```bash
|
||||||
|
docker-compose down
|
||||||
|
docker-compose build
|
||||||
|
docker-compose up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2025-06-08: Zeitzone-Fix - PostgreSQL Timestamps
|
||||||
|
|
||||||
|
**Problem nach erster Implementierung:**
|
||||||
|
- Trotz Zeitzoneneinstellung wurden Zeiten immer noch in UTC angezeigt
|
||||||
|
- Grund: PostgreSQL Tabellen verwendeten `TIMESTAMP WITHOUT TIME ZONE`
|
||||||
|
|
||||||
|
**Zusätzliche Lösung:**
|
||||||
|
1. **Datenbankschema angepasst:**
|
||||||
|
- Alle `TIMESTAMP` Spalten auf `TIMESTAMP WITH TIME ZONE` geändert
|
||||||
|
- Betrifft: created_at, timestamp, started_at, ended_at, last_heartbeat, etc.
|
||||||
|
- Migration für bestehende Datenbanken berücksichtigt
|
||||||
|
|
||||||
|
2. **SQL-Abfragen vereinfacht:**
|
||||||
|
- `AT TIME ZONE 'Europe/Berlin'` nicht mehr nötig
|
||||||
|
- PostgreSQL handhabt Zeitzonenkonvertierung automatisch
|
||||||
|
|
||||||
|
**Geänderte Datei:**
|
||||||
|
- `v2_adminpanel/init.sql`: Alle TIMESTAMP Felder mit WITH TIME ZONE
|
||||||
|
|
||||||
|
**Wichtig:** Bei bestehenden Installationen muss die Datenbank neu initialisiert oder manuell migriert werden:
|
||||||
|
```sql
|
||||||
|
ALTER TABLE customers ALTER COLUMN created_at TYPE TIMESTAMP WITH TIME ZONE;
|
||||||
|
ALTER TABLE licenses ALTER COLUMN created_at TYPE TIMESTAMP WITH TIME ZONE;
|
||||||
|
ALTER TABLE sessions ALTER COLUMN started_at TYPE TIMESTAMP WITH TIME ZONE;
|
||||||
|
ALTER TABLE sessions ALTER COLUMN last_heartbeat TYPE TIMESTAMP WITH TIME ZONE;
|
||||||
|
ALTER TABLE sessions ALTER COLUMN ended_at TYPE TIMESTAMP WITH TIME ZONE;
|
||||||
|
ALTER TABLE audit_log ALTER COLUMN timestamp TYPE TIMESTAMP WITH TIME ZONE;
|
||||||
|
ALTER TABLE backup_history ALTER COLUMN created_at TYPE TIMESTAMP WITH TIME ZONE;
|
||||||
|
ALTER TABLE login_attempts ALTER COLUMN first_attempt TYPE TIMESTAMP WITH TIME ZONE;
|
||||||
|
ALTER TABLE login_attempts ALTER COLUMN last_attempt TYPE TIMESTAMP WITH TIME ZONE;
|
||||||
|
ALTER TABLE login_attempts ALTER COLUMN blocked_until TYPE TIMESTAMP WITH TIME ZONE;
|
||||||
|
```
|
||||||
1
backups/backup_v2docker_20250608_075834_encrypted.sql.gz.enc
Normale Datei
1
backups/backup_v2docker_20250608_075834_encrypted.sql.gz.enc
Normale Datei
Dateidiff unterdrückt, weil mindestens eine Zeile zu lang ist
1
backups/backup_v2docker_20250608_174930_encrypted.sql.gz.enc
Normale Datei
1
backups/backup_v2docker_20250608_174930_encrypted.sql.gz.enc
Normale Datei
Dateidiff unterdrückt, weil mindestens eine Zeile zu lang ist
1
backups/backup_v2docker_20250608_200224_encrypted.sql.gz.enc
Normale Datei
1
backups/backup_v2docker_20250608_200224_encrypted.sql.gz.enc
Normale Datei
Dateidiff unterdrückt, weil mindestens eine Zeile zu lang ist
624
v2/backup_before_timezone_change.sql
Normale Datei
624
v2/backup_before_timezone_change.sql
Normale Datei
@@ -0,0 +1,624 @@
|
|||||||
|
--
|
||||||
|
-- PostgreSQL database dump
|
||||||
|
--
|
||||||
|
|
||||||
|
-- Dumped from database version 14.18 (Debian 14.18-1.pgdg120+1)
|
||||||
|
-- Dumped by pg_dump version 14.18 (Debian 14.18-1.pgdg120+1)
|
||||||
|
|
||||||
|
SET statement_timeout = 0;
|
||||||
|
SET lock_timeout = 0;
|
||||||
|
SET idle_in_transaction_session_timeout = 0;
|
||||||
|
SET client_encoding = 'UTF8';
|
||||||
|
SET standard_conforming_strings = on;
|
||||||
|
SELECT pg_catalog.set_config('search_path', '', false);
|
||||||
|
SET check_function_bodies = false;
|
||||||
|
SET xmloption = content;
|
||||||
|
SET client_min_messages = warning;
|
||||||
|
SET row_security = off;
|
||||||
|
|
||||||
|
SET default_tablespace = '';
|
||||||
|
|
||||||
|
SET default_table_access_method = heap;
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: audit_log; Type: TABLE; Schema: public; Owner: adminuser
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE TABLE public.audit_log (
|
||||||
|
id integer NOT NULL,
|
||||||
|
"timestamp" timestamp without time zone DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
username text NOT NULL,
|
||||||
|
action text NOT NULL,
|
||||||
|
entity_type text NOT NULL,
|
||||||
|
entity_id integer,
|
||||||
|
old_values jsonb,
|
||||||
|
new_values jsonb,
|
||||||
|
ip_address text,
|
||||||
|
user_agent text,
|
||||||
|
additional_info text
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
ALTER TABLE public.audit_log OWNER TO adminuser;
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: audit_log_id_seq; Type: SEQUENCE; Schema: public; Owner: adminuser
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE SEQUENCE public.audit_log_id_seq
|
||||||
|
AS integer
|
||||||
|
START WITH 1
|
||||||
|
INCREMENT BY 1
|
||||||
|
NO MINVALUE
|
||||||
|
NO MAXVALUE
|
||||||
|
CACHE 1;
|
||||||
|
|
||||||
|
|
||||||
|
ALTER TABLE public.audit_log_id_seq OWNER TO adminuser;
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: audit_log_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: adminuser
|
||||||
|
--
|
||||||
|
|
||||||
|
ALTER SEQUENCE public.audit_log_id_seq OWNED BY public.audit_log.id;
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: backup_history; Type: TABLE; Schema: public; Owner: adminuser
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE TABLE public.backup_history (
|
||||||
|
id integer NOT NULL,
|
||||||
|
filename text NOT NULL,
|
||||||
|
filepath text NOT NULL,
|
||||||
|
filesize bigint,
|
||||||
|
backup_type text NOT NULL,
|
||||||
|
status text NOT NULL,
|
||||||
|
error_message text,
|
||||||
|
created_at timestamp without time zone DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
created_by text NOT NULL,
|
||||||
|
tables_count integer,
|
||||||
|
records_count integer,
|
||||||
|
duration_seconds numeric,
|
||||||
|
is_encrypted boolean DEFAULT true
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
ALTER TABLE public.backup_history OWNER TO adminuser;
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: backup_history_id_seq; Type: SEQUENCE; Schema: public; Owner: adminuser
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE SEQUENCE public.backup_history_id_seq
|
||||||
|
AS integer
|
||||||
|
START WITH 1
|
||||||
|
INCREMENT BY 1
|
||||||
|
NO MINVALUE
|
||||||
|
NO MAXVALUE
|
||||||
|
CACHE 1;
|
||||||
|
|
||||||
|
|
||||||
|
ALTER TABLE public.backup_history_id_seq OWNER TO adminuser;
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: backup_history_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: adminuser
|
||||||
|
--
|
||||||
|
|
||||||
|
ALTER SEQUENCE public.backup_history_id_seq OWNED BY public.backup_history.id;
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: customers; Type: TABLE; Schema: public; Owner: adminuser
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE TABLE public.customers (
|
||||||
|
id integer NOT NULL,
|
||||||
|
name text NOT NULL,
|
||||||
|
email text,
|
||||||
|
created_at timestamp without time zone DEFAULT CURRENT_TIMESTAMP
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
ALTER TABLE public.customers OWNER TO adminuser;
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: customers_id_seq; Type: SEQUENCE; Schema: public; Owner: adminuser
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE SEQUENCE public.customers_id_seq
|
||||||
|
AS integer
|
||||||
|
START WITH 1
|
||||||
|
INCREMENT BY 1
|
||||||
|
NO MINVALUE
|
||||||
|
NO MAXVALUE
|
||||||
|
CACHE 1;
|
||||||
|
|
||||||
|
|
||||||
|
ALTER TABLE public.customers_id_seq OWNER TO adminuser;
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: customers_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: adminuser
|
||||||
|
--
|
||||||
|
|
||||||
|
ALTER SEQUENCE public.customers_id_seq OWNED BY public.customers.id;
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: licenses; Type: TABLE; Schema: public; Owner: adminuser
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE TABLE public.licenses (
|
||||||
|
id integer NOT NULL,
|
||||||
|
license_key text NOT NULL,
|
||||||
|
customer_id integer,
|
||||||
|
license_type text NOT NULL,
|
||||||
|
valid_from date NOT NULL,
|
||||||
|
valid_until date NOT NULL,
|
||||||
|
is_active boolean DEFAULT true
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
ALTER TABLE public.licenses OWNER TO adminuser;
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: licenses_id_seq; Type: SEQUENCE; Schema: public; Owner: adminuser
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE SEQUENCE public.licenses_id_seq
|
||||||
|
AS integer
|
||||||
|
START WITH 1
|
||||||
|
INCREMENT BY 1
|
||||||
|
NO MINVALUE
|
||||||
|
NO MAXVALUE
|
||||||
|
CACHE 1;
|
||||||
|
|
||||||
|
|
||||||
|
ALTER TABLE public.licenses_id_seq OWNER TO adminuser;
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: licenses_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: adminuser
|
||||||
|
--
|
||||||
|
|
||||||
|
ALTER SEQUENCE public.licenses_id_seq OWNED BY public.licenses.id;
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: login_attempts; Type: TABLE; Schema: public; Owner: adminuser
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE TABLE public.login_attempts (
|
||||||
|
ip_address character varying(45) NOT NULL,
|
||||||
|
attempt_count integer DEFAULT 0,
|
||||||
|
first_attempt timestamp without time zone DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
last_attempt timestamp without time zone DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
blocked_until timestamp without time zone,
|
||||||
|
last_username_tried text,
|
||||||
|
last_error_message text
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
ALTER TABLE public.login_attempts OWNER TO adminuser;
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: sessions; Type: TABLE; Schema: public; Owner: adminuser
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE TABLE public.sessions (
|
||||||
|
id integer NOT NULL,
|
||||||
|
license_id integer,
|
||||||
|
session_id text NOT NULL,
|
||||||
|
ip_address text,
|
||||||
|
user_agent text,
|
||||||
|
started_at timestamp without time zone DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
last_heartbeat timestamp without time zone DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
ended_at timestamp without time zone,
|
||||||
|
is_active boolean DEFAULT true
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
ALTER TABLE public.sessions OWNER TO adminuser;
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: sessions_id_seq; Type: SEQUENCE; Schema: public; Owner: adminuser
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE SEQUENCE public.sessions_id_seq
|
||||||
|
AS integer
|
||||||
|
START WITH 1
|
||||||
|
INCREMENT BY 1
|
||||||
|
NO MINVALUE
|
||||||
|
NO MAXVALUE
|
||||||
|
CACHE 1;
|
||||||
|
|
||||||
|
|
||||||
|
ALTER TABLE public.sessions_id_seq OWNER TO adminuser;
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: sessions_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: adminuser
|
||||||
|
--
|
||||||
|
|
||||||
|
ALTER SEQUENCE public.sessions_id_seq OWNED BY public.sessions.id;
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: audit_log id; Type: DEFAULT; Schema: public; Owner: adminuser
|
||||||
|
--
|
||||||
|
|
||||||
|
ALTER TABLE ONLY public.audit_log ALTER COLUMN id SET DEFAULT nextval('public.audit_log_id_seq'::regclass);
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: backup_history id; Type: DEFAULT; Schema: public; Owner: adminuser
|
||||||
|
--
|
||||||
|
|
||||||
|
ALTER TABLE ONLY public.backup_history ALTER COLUMN id SET DEFAULT nextval('public.backup_history_id_seq'::regclass);
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: customers id; Type: DEFAULT; Schema: public; Owner: adminuser
|
||||||
|
--
|
||||||
|
|
||||||
|
ALTER TABLE ONLY public.customers ALTER COLUMN id SET DEFAULT nextval('public.customers_id_seq'::regclass);
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: licenses id; Type: DEFAULT; Schema: public; Owner: adminuser
|
||||||
|
--
|
||||||
|
|
||||||
|
ALTER TABLE ONLY public.licenses ALTER COLUMN id SET DEFAULT nextval('public.licenses_id_seq'::regclass);
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: sessions id; Type: DEFAULT; Schema: public; Owner: adminuser
|
||||||
|
--
|
||||||
|
|
||||||
|
ALTER TABLE ONLY public.sessions ALTER COLUMN id SET DEFAULT nextval('public.sessions_id_seq'::regclass);
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Data for Name: audit_log; Type: TABLE DATA; Schema: public; Owner: adminuser
|
||||||
|
--
|
||||||
|
|
||||||
|
COPY public.audit_log (id, "timestamp", username, action, entity_type, entity_id, old_values, new_values, ip_address, user_agent, additional_info) FROM stdin;
|
||||||
|
1 2025-06-07 14:40:45.833151 rac00n LOGIN user \N \N \N 172.19.0.1 Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36 Erfolgreiche Anmeldung
|
||||||
|
2 2025-06-07 14:41:11.190149 rac00n LOGOUT user \N \N \N 172.19.0.1 Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36 Abmeldung
|
||||||
|
3 2025-06-07 14:41:17.105596 rac00n LOGIN user \N \N \N 172.19.0.1 Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36 Erfolgreiche Anmeldung
|
||||||
|
4 2025-06-07 15:15:06.256545 rac00n LOGIN user \N \N \N 172.19.0.1 Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36 Erfolgreiche Anmeldung
|
||||||
|
5 2025-06-07 15:15:33.972469 rac00n LOGIN user \N \N \N 172.19.0.1 curl/8.5.0 Erfolgreiche Anmeldung
|
||||||
|
6 2025-06-07 15:15:34.109986 rac00n BACKUP database 1 \N \N 172.19.0.1 curl/8.5.0 Backup erstellt: backup_v2docker_20250607_151534_encrypted.sql.gz.enc (3640 bytes)
|
||||||
|
7 2025-06-07 15:15:43.824357 rac00n LOGIN user \N \N \N 172.19.0.1 curl/8.5.0 Erfolgreiche Anmeldung
|
||||||
|
8 2025-06-07 15:15:43.912466 rac00n BACKUP database 2 \N \N 172.19.0.1 curl/8.5.0 Backup erstellt: backup_v2docker_20250607_151543_encrypted.sql.gz.enc (3768 bytes)
|
||||||
|
9 2025-06-07 15:16:23.724322 rac00n DOWNLOAD backup 2 \N \N 172.19.0.1 curl/8.5.0 Backup heruntergeladen: backup_v2docker_20250607_151543_encrypted.sql.gz.enc
|
||||||
|
76 2025-06-08 07:55:31.892854 rac00n LOGIN_SUCCESS user \N \N \N 172.19.0.5 Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36 Erfolgreiche Anmeldung von IP: 172.19.0.1
|
||||||
|
78 2025-06-08 07:59:05.01361 rac00n DOWNLOAD backup 5 \N \N 172.19.0.5 Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36 Backup heruntergeladen: backup_v2docker_20250608_075834_encrypted.sql.gz.enc
|
||||||
|
80 2025-06-08 08:06:18.479631 rac00n LOGIN_SUCCESS user \N \N \N 172.19.0.5 Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/28.0 Chrome/130.0.0.0 Mobile Safari/537.36 Erfolgreiche Anmeldung von IP: 172.19.0.1
|
||||||
|
82 2025-06-08 14:36:01.730846 rac00n LOGIN_SUCCESS user \N \N \N 172.19.0.5 Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36 Erfolgreiche Anmeldung von IP: 172.19.0.1
|
||||||
|
84 2025-06-08 16:13:31.837749 rac00n LOGIN_SUCCESS user \N \N \N 172.19.0.5 Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36 Erfolgreiche Anmeldung von IP: 172.19.0.1
|
||||||
|
86 2025-06-08 17:47:45.942574 rac00n LOGIN_SUCCESS user \N \N \N 172.19.0.5 python-requests/2.31.0 Erfolgreiche Anmeldung von IP: 172.19.0.1
|
||||||
|
10 2025-06-07 17:01:30.363152 w@rh@mm3r LOGOUT user \N \N \N 172.19.0.5 Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36 Abmeldung
|
||||||
|
11 2025-06-07 17:11:08.302021 w@rh@mm3r LOGIN user \N \N \N 172.19.0.5 Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36 Erfolgreiche Anmeldung
|
||||||
|
12 2025-06-07 17:11:10.058681 w@rh@mm3r LOGOUT user \N \N \N 172.19.0.5 Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36 Abmeldung
|
||||||
|
13 2025-06-07 17:11:17.726581 rac00n LOGIN user \N \N \N 172.19.0.5 Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36 Erfolgreiche Anmeldung
|
||||||
|
14 2025-06-07 17:37:01.770454 rac00n LOGIN user \N \N \N 172.19.0.5 Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36 Erfolgreiche Anmeldung
|
||||||
|
15 2025-06-07 17:45:53.454599 rac00n LOGIN user \N \N \N 172.19.0.5 curl/8.5.0 Erfolgreiche Anmeldung
|
||||||
|
16 2025-06-07 17:46:45.804984 rac00n BACKUP database 3 \N \N 172.19.0.5 curl/8.5.0 Backup erstellt: backup_v2docker_20250607_174645_encrypted.sql.gz.enc (4108 bytes)
|
||||||
|
17 2025-06-07 17:54:25.805772 rac00n LOGIN user \N \N \N 172.19.0.5 Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36 Erfolgreiche Anmeldung
|
||||||
|
18 2025-06-07 17:54:30.18286 rac00n LOGOUT user \N \N \N 172.19.0.5 Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36 Abmeldung
|
||||||
|
19 2025-06-07 18:02:18.1851 rac00n LOGIN user \N \N \N 172.19.0.5 Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36 Erfolgreiche Anmeldung
|
||||||
|
20 2025-06-07 18:55:11.584957 system LOGIN_FAILED user \N \N \N 172.19.0.5 curl/8.5.0 IP: 172.19.0.1, User: testuser, Message: YOU FAILED
|
||||||
|
21 2025-06-07 18:55:13.112779 system LOGIN_FAILED user \N \N \N 172.19.0.5 curl/8.5.0 IP: 172.19.0.1, User: testuser, Message: WRONG! 🚫
|
||||||
|
22 2025-06-07 19:00:59.418824 rac00n LOGIN_SUCCESS user \N \N \N 172.19.0.5 Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36 Erfolgreiche Anmeldung von IP: 172.19.0.1
|
||||||
|
23 2025-06-07 19:01:54.566099 rac00n LOGOUT user \N \N \N 172.19.0.5 Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36 Abmeldung
|
||||||
|
24 2025-06-07 19:03:45.046523 rac00n LOGIN_SUCCESS user \N \N \N 172.19.0.5 Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36 Erfolgreiche Anmeldung von IP: 172.19.0.1
|
||||||
|
25 2025-06-07 19:31:13.237177 rac00n LOGIN_SUCCESS user \N \N \N 172.19.0.5 Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36 Erfolgreiche Anmeldung von IP: 172.19.0.1
|
||||||
|
26 2025-06-07 19:32:20.003266 rac00n LOGIN_SUCCESS user \N \N \N 172.19.0.5 Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36 Erfolgreiche Anmeldung von IP: 172.19.0.1
|
||||||
|
27 2025-06-07 19:33:26.379968 rac00n LOGIN_SUCCESS user \N \N \N 172.19.0.5 Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36 Erfolgreiche Anmeldung von IP: 172.19.0.1
|
||||||
|
28 2025-06-07 19:34:09.072085 rac00n LOGOUT user \N \N \N 172.19.0.5 Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36 Abmeldung
|
||||||
|
29 2025-06-07 19:36:17.489882 rac00n LOGIN_SUCCESS user \N \N \N 172.19.0.5 curl/8.5.0 Erfolgreiche Anmeldung von IP: 172.19.0.1
|
||||||
|
30 2025-06-07 19:44:27.078563 rac00n LOGIN_SUCCESS user \N \N \N 172.19.0.5 Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36 Erfolgreiche Anmeldung von IP: 172.19.0.1
|
||||||
|
31 2025-06-07 19:51:17.993707 rac00n LOGIN_SUCCESS user \N \N \N 172.19.0.5 curl/8.5.0 Erfolgreiche Anmeldung von IP: 172.19.0.1
|
||||||
|
32 2025-06-07 19:58:17.448169 rac00n LOGIN_SUCCESS user \N \N \N 172.19.0.5 Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36 Erfolgreiche Anmeldung von IP: 172.19.0.1
|
||||||
|
33 2025-06-07 19:58:52.291492 rac00n LOGOUT user \N \N \N 172.19.0.5 Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36 Abmeldung
|
||||||
|
34 2025-06-07 20:03:15.20645 rac00n LOGIN_SUCCESS user \N \N \N 172.19.0.5 Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36 Erfolgreiche Anmeldung von IP: 172.19.0.1
|
||||||
|
35 2025-06-07 20:05:19.654401 rac00n LOGIN_SUCCESS user \N \N \N 172.19.0.5 curl/8.5.0 Erfolgreiche Anmeldung von IP: 172.19.0.1
|
||||||
|
36 2025-06-07 20:11:25.331298 rac00n LOGIN_SUCCESS user \N \N \N 172.19.0.5 curl/8.5.0 Erfolgreiche Anmeldung von IP: 172.19.0.1
|
||||||
|
37 2025-06-07 20:49:37.631513 rac00n LOGIN_SUCCESS user \N \N \N 172.19.0.5 curl/8.5.0 Erfolgreiche Anmeldung von IP: 172.19.0.1
|
||||||
|
38 2025-06-07 20:52:27.354576 rac00n LOGIN_SUCCESS user \N \N \N 172.19.0.5 curl/8.5.0 Erfolgreiche Anmeldung von IP: 172.19.0.1
|
||||||
|
39 2025-06-07 20:52:27.38643 rac00n EXPORT license \N \N \N 172.19.0.5 curl/8.5.0 Export aller Lizenzen als CSV
|
||||||
|
40 2025-06-07 20:54:04.783715 rac00n LOGIN_SUCCESS user \N \N \N 172.19.0.5 Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36 Erfolgreiche Anmeldung von IP: 172.19.0.1
|
||||||
|
41 2025-06-07 20:56:50.950356 rac00n LOGIN_SUCCESS user \N \N \N 172.19.0.5 Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36 Erfolgreiche Anmeldung von IP: 172.19.0.1
|
||||||
|
42 2025-06-07 21:06:51.653154 rac00n LOGIN_SUCCESS user \N \N \N 172.19.0.5 curl/8.5.0 Erfolgreiche Anmeldung von IP: 172.19.0.1
|
||||||
|
43 2025-06-07 21:12:07.627636 rac00n LOGIN_SUCCESS user \N \N \N 172.19.0.5 Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36 Erfolgreiche Anmeldung von IP: 172.19.0.1
|
||||||
|
44 2025-06-07 21:45:19.164825 rac00n LOGIN_SUCCESS user \N \N \N 172.19.0.5 Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36 Erfolgreiche Anmeldung von IP: 172.19.0.1
|
||||||
|
45 2025-06-07 21:56:57.616336 rac00n LOGIN_SUCCESS user \N \N \N 172.19.0.5 Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36 Erfolgreiche Anmeldung von IP: 172.19.0.1
|
||||||
|
46 2025-06-07 21:58:35.15561 rac00n CREATE license 1 \N {"valid_from": "2025-06-07", "license_key": "AF-202506T-75R4-9M9H-DFEY", "valid_until": "2025-06-13", "license_type": "test", "customer_name": "Demo Firma GmbH", "customer_email": "demo@firma.de"} 172.19.0.5 Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36 \N
|
||||||
|
47 2025-06-07 22:01:01.548875 rac00n LOGIN_SUCCESS user \N \N \N 172.19.0.5 Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36 Erfolgreiche Anmeldung von IP: 172.19.0.1
|
||||||
|
48 2025-06-07 22:01:28.294051 rac00n CREATE license 2 \N {"valid_from": "2025-06-07", "license_key": "AF-202506T-3DF2-ELJN-RQDR", "valid_until": "2025-06-20", "license_type": "test", "customer_name": "Test Kunde", "customer_email": "test@example.com"} 172.19.0.5 Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36 \N
|
||||||
|
49 2025-06-07 22:19:17.155373 rac00n LOGIN_SUCCESS user \N \N \N 172.19.0.5 Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36 Erfolgreiche Anmeldung von IP: 172.19.0.1
|
||||||
|
50 2025-06-07 22:19:29.307415 rac00n CREATE license 3 \N {"valid_from": "2025-06-07", "license_key": "AF-202506F-CRS3-PL6W-9CCP", "valid_until": "2026-06-06", "license_type": "full", "customer_name": "Test vor Restore", "customer_email": "test@restore.de"} 172.19.0.5 Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36 \N
|
||||||
|
51 2025-06-07 22:19:36.9697 rac00n CREATE license 4 \N {"valid_from": "2025-06-07", "license_key": "AF-202506F-GGKA-CJKV-P2PF", "valid_until": "2026-06-06", "license_type": "full", "customer_name": "Test vor Restore", "customer_email": "test@restore.de"} 172.19.0.5 Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36 \N
|
||||||
|
52 2025-06-07 22:19:51.747722 rac00n CREATE_BATCH license \N \N {"type": "full", "customer": "Müller GmbH & Co. KG", "quantity": 10} 172.19.0.5 Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36 Batch-Generierung von 10 Lizenzen
|
||||||
|
53 2025-06-07 22:23:56.496775 rac00n LOGIN_SUCCESS user \N \N \N 172.19.0.5 Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36 Erfolgreiche Anmeldung von IP: 172.19.0.1
|
||||||
|
54 2025-06-07 22:24:29.52332 rac00n UPDATE customer 4 {"name": "Demo Firma GmbH", "email": "demo@firma.de"} {"name": "Demo Firma GmbH oder so ähnlich", "email": "demo@firma.de"} 172.19.0.5 Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36 \N
|
||||||
|
55 2025-06-07 22:24:53.387461 rac00n UPDATE license 14 {"is_active": true, "valid_from": "2025-06-07", "license_key": "AF-202506F-Z6KT-QY28-CTZ9", "valid_until": "2026-06-06", "license_type": "full"} {"is_active": false, "valid_from": "2025-06-07", "license_key": "AF-202506F-Z6KT-QY28-CTZ9", "valid_until": "2026-06-06", "license_type": "full"} 172.19.0.5 Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36 \N
|
||||||
|
56 2025-06-07 22:25:42.636503 rac00n LOGIN_SUCCESS user \N \N \N 172.19.0.5 Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36 Erfolgreiche Anmeldung von IP: 172.19.0.1
|
||||||
|
57 2025-06-07 22:26:04.176345 rac00n LOGIN_SUCCESS user \N \N \N 172.19.0.5 Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36 Erfolgreiche Anmeldung von IP: 172.19.0.1
|
||||||
|
58 2025-06-07 22:32:36.918402 rac00n LOGIN_SUCCESS user \N \N \N 172.19.0.5 Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36 Erfolgreiche Anmeldung von IP: 172.19.0.1
|
||||||
|
59 2025-06-07 22:33:04.289738 rac00n UPDATE license 12 {"is_active": true, "valid_from": "2025-06-07", "license_key": "AF-202506F-F6E8-2KXL-7GVB", "valid_until": "2026-06-06", "license_type": "full"} {"is_active": false, "valid_from": "2025-06-07", "license_key": "AF-202506F-F6E8-2KXL-7GVB", "valid_until": "2026-06-06", "license_type": "full"} 172.19.0.5 Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36 \N
|
||||||
|
60 2025-06-07 22:37:11.24327 rac00n LOGIN_SUCCESS user \N \N \N 172.19.0.5 Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36 Erfolgreiche Anmeldung von IP: 172.19.0.1
|
||||||
|
61 2025-06-07 22:40:11.528994 rac00n LOGIN_SUCCESS user \N \N \N 172.19.0.5 Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36 Erfolgreiche Anmeldung von IP: 172.19.0.1
|
||||||
|
62 2025-06-07 23:02:03.858286 system LOGIN_FAILED user \N \N \N 172.19.0.5 Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36 IP: 172.19.0.1, User: rac00n, Message: YOU FAILED
|
||||||
|
63 2025-06-07 23:02:13.590411 system LOGIN_FAILED user \N \N \N 172.19.0.5 Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36 IP: 172.19.0.1, User: rac00n, Message: COMPUTER SAYS NO
|
||||||
|
64 2025-06-07 23:18:04.017897 system LOGIN_FAILED user \N \N \N 172.19.0.5 Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36 IP: 172.19.0.1, User: rac00n, Message: NOPE!
|
||||||
|
65 2025-06-07 23:18:45.316866 rac00n LOGIN_SUCCESS user \N \N \N 172.19.0.5 Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36 Erfolgreiche Anmeldung von IP: 172.19.0.1
|
||||||
|
66 2025-06-07 23:24:10.758514 rac00n CREATE customer 6 \N {"name": "Bli Bla Blub GmbH", "email": "test@bliblablu.info"} 172.19.0.5 Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36 \N
|
||||||
|
67 2025-06-07 23:24:10.763695 rac00n CREATE license 15 \N {"valid_from": "2025-06-08", "license_key": "AF-202506T-R5TC-9KT3-ZPRD", "valid_until": "2025-07-07", "license_type": "full", "customer_name": "Bli Bla Blub GmbH", "customer_email": "test@bliblablu.info"} 172.19.0.5 Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36 \N
|
||||||
|
68 2025-06-07 23:25:25.589172 rac00n UPDATE license 14 {"is_active": false, "valid_from": "2025-06-07", "license_key": "AF-202506F-Z6KT-QY28-CTZ9", "valid_until": "2026-06-06", "license_type": "full"} {"is_active": false, "valid_from": "2025-06-07", "license_key": "AF-202506F-Z6KT-QY28-CTZ9", "valid_until": "2026-06-06", "license_type": "full"} 172.19.0.5 Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36 \N
|
||||||
|
69 2025-06-07 23:25:33.134625 rac00n UPDATE license 11 {"is_active": true, "valid_from": "2025-06-07", "license_key": "AF-202506F-A6BV-6KAX-KU4J", "valid_until": "2026-06-06", "license_type": "full"} {"is_active": false, "valid_from": "2025-06-07", "license_key": "AF-202506F-A6BV-6KAX-KU4J", "valid_until": "2026-06-06", "license_type": "full"} 172.19.0.5 Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36 \N
|
||||||
|
70 2025-06-07 23:25:52.026955 rac00n DELETE license 14 {"license_key": "AF-202506F-Z6KT-QY28-CTZ9", "license_type": "full", "customer_name": "Müller GmbH & Co. KG"} \N 172.19.0.5 Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36 \N
|
||||||
|
71 2025-06-07 23:26:34.32667 rac00n DELETE customer 5 {"name": "Max Mustermann", "email": "max@mustermann.de"} \N 172.19.0.5 Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36 \N
|
||||||
|
72 2025-06-07 23:27:11.170417 rac00n CREATE_BATCH license \N \N {"type": "full", "customer": "Bli Bla Blub GmbH", "quantity": 5} 172.19.0.5 Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36 Batch-Generierung von 5 Lizenzen
|
||||||
|
73 2025-06-07 23:28:45.926809 rac00n BACKUP database 4 \N \N 172.19.0.5 Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36 Backup erstellt: backup_v2docker_20250607_232845_encrypted.sql.gz.enc (7116 bytes)
|
||||||
|
74 2025-06-07 23:29:10.885674 rac00n DOWNLOAD backup 4 \N \N 172.19.0.5 Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36 Backup heruntergeladen: backup_v2docker_20250607_232845_encrypted.sql.gz.enc
|
||||||
|
75 2025-06-08 07:55:19.354464 system LOGIN_FAILED user \N \N \N 172.19.0.5 Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36 IP: 172.19.0.1, User: rac00n, Message: NOPE!
|
||||||
|
77 2025-06-08 07:58:34.270119 rac00n BACKUP database 5 \N \N 172.19.0.5 Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36 Backup erstellt: backup_v2docker_20250608_075834_encrypted.sql.gz.enc (7308 bytes)
|
||||||
|
79 2025-06-08 07:59:21.636378 rac00n LOGOUT user \N \N \N 172.19.0.5 Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36 Abmeldung
|
||||||
|
81 2025-06-08 08:51:01.683507 rac00n LOGIN_SUCCESS user \N \N \N 172.19.0.5 Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/28.0 Chrome/130.0.0.0 Mobile Safari/537.36 Erfolgreiche Anmeldung von IP: 172.19.0.1
|
||||||
|
83 2025-06-08 14:36:24.980042 rac00n LOGOUT user \N \N \N 172.19.0.5 Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36 Abmeldung
|
||||||
|
85 2025-06-08 17:21:27.353725 rac00n LOGIN_SUCCESS user \N \N \N 172.19.0.5 Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36 Erfolgreiche Anmeldung von IP: 172.19.0.1
|
||||||
|
87 2025-06-08 17:49:18.527739 rac00n LOGIN_SUCCESS user \N \N \N 172.19.0.5 python-requests/2.31.0 Erfolgreiche Anmeldung von IP: 172.19.0.1
|
||||||
|
88 2025-06-08 17:49:31.018007 rac00n BACKUP database 6 \N \N 172.19.0.5 python-requests/2.31.0 Backup erstellt: backup_v2docker_20250608_174930_encrypted.sql.gz.enc (7692 bytes)
|
||||||
|
89 2025-06-08 17:50:12.342288 rac00n LOGIN_SUCCESS user \N \N \N 172.19.0.5 python-requests/2.31.0 Erfolgreiche Anmeldung von IP: 172.19.0.1
|
||||||
|
90 2025-06-08 18:01:50.515914 rac00n LOGIN_SUCCESS user \N \N \N 172.19.0.5 Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36 Erfolgreiche Anmeldung von IP: 172.19.0.1
|
||||||
|
91 2025-06-08 18:02:24.836845 rac00n BACKUP database 7 \N \N 172.19.0.5 Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36 Backup erstellt: backup_v2docker_20250608_200224_encrypted.sql.gz.enc (7864 bytes)
|
||||||
|
92 2025-06-08 18:02:35.914193 rac00n LOGOUT user \N \N \N 172.19.0.5 Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36 Abmeldung
|
||||||
|
93 2025-06-08 18:04:57.805724 system LOGOUT user \N \N \N 172.19.0.5 python-requests/2.31.0 Abmeldung
|
||||||
|
94 2025-06-08 18:04:59.88908 rac00n LOGIN_SUCCESS user \N \N \N 172.19.0.5 python-requests/2.31.0 Erfolgreiche Anmeldung von IP: 172.19.0.1
|
||||||
|
95 2025-06-08 18:06:51.462396 rac00n LOGIN_SUCCESS user \N \N \N 172.19.0.5 python-requests/2.31.0 Erfolgreiche Anmeldung von IP: 172.19.0.1
|
||||||
|
96 2025-06-08 18:10:13.065749 rac00n LOGIN_SUCCESS user \N \N \N 172.19.0.5 Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36 Erfolgreiche Anmeldung von IP: 172.19.0.1
|
||||||
|
\.
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Data for Name: backup_history; Type: TABLE DATA; Schema: public; Owner: adminuser
|
||||||
|
--
|
||||||
|
|
||||||
|
COPY public.backup_history (id, filename, filepath, filesize, backup_type, status, error_message, created_at, created_by, tables_count, records_count, duration_seconds, is_encrypted) FROM stdin;
|
||||||
|
1 backup_v2docker_20250607_151534_encrypted.sql.gz.enc /app/backups/backup_v2docker_20250607_151534_encrypted.sql.gz.enc 3640 manual success \N 2025-06-07 15:15:34.003903 rac00n 5 6 0.1055765151977539 t
|
||||||
|
2 backup_v2docker_20250607_151543_encrypted.sql.gz.enc /app/backups/backup_v2docker_20250607_151543_encrypted.sql.gz.enc 3768 manual success \N 2025-06-07 15:15:43.853153 rac00n 5 9 0.058580875396728516 t
|
||||||
|
3 backup_v2docker_20250607_174645_encrypted.sql.gz.enc /app/backups/backup_v2docker_20250607_174645_encrypted.sql.gz.enc 4108 manual success \N 2025-06-07 17:46:45.701839 rac00n 5 19 0.10155487060546875 t
|
||||||
|
4 backup_v2docker_20250607_232845_encrypted.sql.gz.enc /app/backups/backup_v2docker_20250607_232845_encrypted.sql.gz.enc 7116 manual success \N 2025-06-07 23:28:45.823584 rac00n 6 102 0.10189580917358398 t
|
||||||
|
5 backup_v2docker_20250608_075834_encrypted.sql.gz.enc /app/backups/backup_v2docker_20250608_075834_encrypted.sql.gz.enc 7308 manual success \N 2025-06-08 07:58:34.205649 rac00n 6 107 0.06303167343139648 t
|
||||||
|
6 backup_v2docker_20250608_174930_encrypted.sql.gz.enc /app/backups/backup_v2docker_20250608_174930_encrypted.sql.gz.enc 7692 manual success \N 2025-06-08 17:49:30.953077 rac00n 6 119 0.06305289268493652 t
|
||||||
|
7 backup_v2docker_20250608_200224_encrypted.sql.gz.enc /app/backups/backup_v2docker_20250608_200224_encrypted.sql.gz.enc 7864 manual success \N 2025-06-08 18:02:24.771159 rac00n 6 123 0.06486988067626953 t
|
||||||
|
\.
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Data for Name: customers; Type: TABLE DATA; Schema: public; Owner: adminuser
|
||||||
|
--
|
||||||
|
|
||||||
|
COPY public.customers (id, name, email, created_at) FROM stdin;
|
||||||
|
1 Müller GmbH & Co. KG kontakt@müller-köln.de 2025-06-07 14:39:21.554354
|
||||||
|
2 Test vor Restore test@restore.de 2025-06-07 15:16:51.26188
|
||||||
|
3 Test Kunde test@example.com 2025-06-07 21:43:48.308699
|
||||||
|
4 Demo Firma GmbH oder so ähnlich demo@firma.de 2025-06-07 21:43:48.308699
|
||||||
|
6 Bli Bla Blub GmbH test@bliblablu.info 2025-06-07 23:24:10.753449
|
||||||
|
\.
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Data for Name: licenses; Type: TABLE DATA; Schema: public; Owner: adminuser
|
||||||
|
--
|
||||||
|
|
||||||
|
COPY public.licenses (id, license_key, customer_id, license_type, valid_from, valid_until, is_active) FROM stdin;
|
||||||
|
1 AF-202506T-75R4-9M9H-DFEY 4 test 2025-06-07 2025-06-13 t
|
||||||
|
2 AF-202506T-3DF2-ELJN-RQDR 3 test 2025-06-07 2025-06-20 t
|
||||||
|
3 AF-202506F-CRS3-PL6W-9CCP 2 full 2025-06-07 2026-06-06 t
|
||||||
|
4 AF-202506F-GGKA-CJKV-P2PF 2 full 2025-06-07 2026-06-06 t
|
||||||
|
5 AF-202506F-FDZQ-MH3T-6EWP 1 full 2025-06-07 2026-06-06 t
|
||||||
|
6 AF-202506F-QYM9-58NT-SRCV 1 full 2025-06-07 2026-06-06 t
|
||||||
|
7 AF-202506F-9AVT-SY3C-KZ6H 1 full 2025-06-07 2026-06-06 t
|
||||||
|
8 AF-202506F-TS34-U93G-X74Y 1 full 2025-06-07 2026-06-06 t
|
||||||
|
9 AF-202506F-PC2K-SPEC-9MDS 1 full 2025-06-07 2026-06-06 t
|
||||||
|
10 AF-202506F-R2VL-J7YF-6XLA 1 full 2025-06-07 2026-06-06 t
|
||||||
|
13 AF-202506F-JU47-AS8Y-8VFP 1 full 2025-06-07 2026-06-06 t
|
||||||
|
12 AF-202506F-F6E8-2KXL-7GVB 1 full 2025-06-07 2026-06-06 f
|
||||||
|
15 AF-202506T-R5TC-9KT3-ZPRD 6 full 2025-06-08 2025-07-07 t
|
||||||
|
11 AF-202506F-A6BV-6KAX-KU4J 1 full 2025-06-07 2026-06-06 f
|
||||||
|
16 AF-202506F-F4WM-RUBG-RR7A 6 full 2025-06-08 2025-07-07 t
|
||||||
|
17 AF-202506F-ZFYY-D2ZG-9D2B 6 full 2025-06-08 2025-07-07 t
|
||||||
|
18 AF-202506F-KS7T-Z676-7V5L 6 full 2025-06-08 2025-07-07 t
|
||||||
|
19 AF-202506F-3NJ4-X5ET-RWY2 6 full 2025-06-08 2025-07-07 t
|
||||||
|
20 AF-202506F-B984-PHN6-BUDX 6 full 2025-06-08 2025-07-07 t
|
||||||
|
\.
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Data for Name: login_attempts; Type: TABLE DATA; Schema: public; Owner: adminuser
|
||||||
|
--
|
||||||
|
|
||||||
|
COPY public.login_attempts (ip_address, attempt_count, first_attempt, last_attempt, blocked_until, last_username_tried, last_error_message) FROM stdin;
|
||||||
|
192.168.1.50 3 2025-06-07 18:56:54.538998 2025-06-07 18:56:54.538998 2025-06-07 20:56:54.538998 attacker1 NOPE\\!
|
||||||
|
10.0.0.25 5 2025-06-07 18:56:54.538998 2025-06-07 18:56:54.538998 2025-06-08 14:56:54.538998 scanner ACCESS DENIED, TRY HARDER
|
||||||
|
192.168.100.200 7 2025-06-07 18:56:54.538998 2025-06-07 18:56:54.538998 2025-06-08 17:56:54.538998 brute_forcer YOU FAILED
|
||||||
|
\.
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Data for Name: sessions; Type: TABLE DATA; Schema: public; Owner: adminuser
|
||||||
|
--
|
||||||
|
|
||||||
|
COPY public.sessions (id, license_id, session_id, ip_address, user_agent, started_at, last_heartbeat, ended_at, is_active) FROM stdin;
|
||||||
|
\.
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: audit_log_id_seq; Type: SEQUENCE SET; Schema: public; Owner: adminuser
|
||||||
|
--
|
||||||
|
|
||||||
|
SELECT pg_catalog.setval('public.audit_log_id_seq', 96, true);
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: backup_history_id_seq; Type: SEQUENCE SET; Schema: public; Owner: adminuser
|
||||||
|
--
|
||||||
|
|
||||||
|
SELECT pg_catalog.setval('public.backup_history_id_seq', 7, true);
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: customers_id_seq; Type: SEQUENCE SET; Schema: public; Owner: adminuser
|
||||||
|
--
|
||||||
|
|
||||||
|
SELECT pg_catalog.setval('public.customers_id_seq', 6, true);
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: licenses_id_seq; Type: SEQUENCE SET; Schema: public; Owner: adminuser
|
||||||
|
--
|
||||||
|
|
||||||
|
SELECT pg_catalog.setval('public.licenses_id_seq', 20, true);
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: sessions_id_seq; Type: SEQUENCE SET; Schema: public; Owner: adminuser
|
||||||
|
--
|
||||||
|
|
||||||
|
SELECT pg_catalog.setval('public.sessions_id_seq', 1, false);
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: audit_log audit_log_pkey; Type: CONSTRAINT; Schema: public; Owner: adminuser
|
||||||
|
--
|
||||||
|
|
||||||
|
ALTER TABLE ONLY public.audit_log
|
||||||
|
ADD CONSTRAINT audit_log_pkey PRIMARY KEY (id);
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: backup_history backup_history_pkey; Type: CONSTRAINT; Schema: public; Owner: adminuser
|
||||||
|
--
|
||||||
|
|
||||||
|
ALTER TABLE ONLY public.backup_history
|
||||||
|
ADD CONSTRAINT backup_history_pkey PRIMARY KEY (id);
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: customers customers_pkey; Type: CONSTRAINT; Schema: public; Owner: adminuser
|
||||||
|
--
|
||||||
|
|
||||||
|
ALTER TABLE ONLY public.customers
|
||||||
|
ADD CONSTRAINT customers_pkey PRIMARY KEY (id);
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: licenses licenses_license_key_key; Type: CONSTRAINT; Schema: public; Owner: adminuser
|
||||||
|
--
|
||||||
|
|
||||||
|
ALTER TABLE ONLY public.licenses
|
||||||
|
ADD CONSTRAINT licenses_license_key_key UNIQUE (license_key);
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: licenses licenses_pkey; Type: CONSTRAINT; Schema: public; Owner: adminuser
|
||||||
|
--
|
||||||
|
|
||||||
|
ALTER TABLE ONLY public.licenses
|
||||||
|
ADD CONSTRAINT licenses_pkey PRIMARY KEY (id);
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: login_attempts login_attempts_pkey; Type: CONSTRAINT; Schema: public; Owner: adminuser
|
||||||
|
--
|
||||||
|
|
||||||
|
ALTER TABLE ONLY public.login_attempts
|
||||||
|
ADD CONSTRAINT login_attempts_pkey PRIMARY KEY (ip_address);
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: sessions sessions_pkey; Type: CONSTRAINT; Schema: public; Owner: adminuser
|
||||||
|
--
|
||||||
|
|
||||||
|
ALTER TABLE ONLY public.sessions
|
||||||
|
ADD CONSTRAINT sessions_pkey PRIMARY KEY (id);
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: sessions sessions_session_id_key; Type: CONSTRAINT; Schema: public; Owner: adminuser
|
||||||
|
--
|
||||||
|
|
||||||
|
ALTER TABLE ONLY public.sessions
|
||||||
|
ADD CONSTRAINT sessions_session_id_key UNIQUE (session_id);
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: idx_audit_log_entity; Type: INDEX; Schema: public; Owner: adminuser
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE INDEX idx_audit_log_entity ON public.audit_log USING btree (entity_type, entity_id);
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: idx_audit_log_timestamp; Type: INDEX; Schema: public; Owner: adminuser
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE INDEX idx_audit_log_timestamp ON public.audit_log USING btree ("timestamp" DESC);
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: idx_audit_log_username; Type: INDEX; Schema: public; Owner: adminuser
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE INDEX idx_audit_log_username ON public.audit_log USING btree (username);
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: idx_backup_history_created_at; Type: INDEX; Schema: public; Owner: adminuser
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE INDEX idx_backup_history_created_at ON public.backup_history USING btree (created_at DESC);
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: idx_backup_history_status; Type: INDEX; Schema: public; Owner: adminuser
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE INDEX idx_backup_history_status ON public.backup_history USING btree (status);
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: idx_login_attempts_blocked_until; Type: INDEX; Schema: public; Owner: adminuser
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE INDEX idx_login_attempts_blocked_until ON public.login_attempts USING btree (blocked_until);
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: idx_login_attempts_last_attempt; Type: INDEX; Schema: public; Owner: adminuser
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE INDEX idx_login_attempts_last_attempt ON public.login_attempts USING btree (last_attempt DESC);
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: licenses licenses_customer_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: adminuser
|
||||||
|
--
|
||||||
|
|
||||||
|
ALTER TABLE ONLY public.licenses
|
||||||
|
ADD CONSTRAINT licenses_customer_id_fkey FOREIGN KEY (customer_id) REFERENCES public.customers(id);
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: sessions sessions_license_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: adminuser
|
||||||
|
--
|
||||||
|
|
||||||
|
ALTER TABLE ONLY public.sessions
|
||||||
|
ADD CONSTRAINT sessions_license_id_fkey FOREIGN KEY (license_id) REFERENCES public.licenses(id);
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- PostgreSQL database dump complete
|
||||||
|
--
|
||||||
|
|
||||||
@@ -12,6 +12,8 @@ services:
|
|||||||
POSTGRES_INITDB_ARGS: '--encoding=UTF8 --locale=de_DE.UTF-8'
|
POSTGRES_INITDB_ARGS: '--encoding=UTF8 --locale=de_DE.UTF-8'
|
||||||
POSTGRES_COLLATE: 'de_DE.UTF-8'
|
POSTGRES_COLLATE: 'de_DE.UTF-8'
|
||||||
POSTGRES_CTYPE: 'de_DE.UTF-8'
|
POSTGRES_CTYPE: 'de_DE.UTF-8'
|
||||||
|
TZ: Europe/Berlin
|
||||||
|
PGTZ: Europe/Berlin
|
||||||
volumes:
|
volumes:
|
||||||
# Persistente Speicherung der Datenbank auf dem Windows-Host
|
# Persistente Speicherung der Datenbank auf dem Windows-Host
|
||||||
- postgres_data:/var/lib/postgresql/data
|
- postgres_data:/var/lib/postgresql/data
|
||||||
@@ -33,6 +35,8 @@ services:
|
|||||||
ports:
|
ports:
|
||||||
- "8443:8443"
|
- "8443:8443"
|
||||||
env_file: .env
|
env_file: .env
|
||||||
|
environment:
|
||||||
|
TZ: Europe/Berlin
|
||||||
depends_on:
|
depends_on:
|
||||||
- postgres
|
- postgres
|
||||||
networks:
|
networks:
|
||||||
@@ -50,6 +54,8 @@ services:
|
|||||||
restart: always
|
restart: always
|
||||||
# Port-Mapping entfernt - nur über nginx erreichbar
|
# Port-Mapping entfernt - nur über nginx erreichbar
|
||||||
env_file: .env
|
env_file: .env
|
||||||
|
environment:
|
||||||
|
TZ: Europe/Berlin
|
||||||
depends_on:
|
depends_on:
|
||||||
- postgres
|
- postgres
|
||||||
networks:
|
networks:
|
||||||
@@ -71,6 +77,8 @@ services:
|
|||||||
ports:
|
ports:
|
||||||
- "80:80"
|
- "80:80"
|
||||||
- "443:443"
|
- "443:443"
|
||||||
|
environment:
|
||||||
|
TZ: Europe/Berlin
|
||||||
depends_on:
|
depends_on:
|
||||||
- admin-panel
|
- admin-panel
|
||||||
- license-server
|
- license-server
|
||||||
|
|||||||
@@ -5,15 +5,21 @@ ENV LANG=de_DE.UTF-8
|
|||||||
ENV LC_ALL=de_DE.UTF-8
|
ENV LC_ALL=de_DE.UTF-8
|
||||||
ENV PYTHONIOENCODING=utf-8
|
ENV PYTHONIOENCODING=utf-8
|
||||||
|
|
||||||
|
# Zeitzone auf Europe/Berlin setzen
|
||||||
|
ENV TZ=Europe/Berlin
|
||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
# System-Dependencies inkl. PostgreSQL-Tools installieren
|
# System-Dependencies inkl. PostgreSQL-Tools installieren
|
||||||
RUN apt-get update && apt-get install -y \
|
RUN apt-get update && apt-get install -y \
|
||||||
locales \
|
locales \
|
||||||
postgresql-client \
|
postgresql-client \
|
||||||
|
tzdata \
|
||||||
&& sed -i '/de_DE.UTF-8/s/^# //g' /etc/locale.gen \
|
&& sed -i '/de_DE.UTF-8/s/^# //g' /etc/locale.gen \
|
||||||
&& locale-gen \
|
&& locale-gen \
|
||||||
&& update-locale LANG=de_DE.UTF-8 \
|
&& update-locale LANG=de_DE.UTF-8 \
|
||||||
|
&& ln -sf /usr/share/zoneinfo/Europe/Berlin /etc/localtime \
|
||||||
|
&& echo "Europe/Berlin" > /etc/timezone \
|
||||||
&& apt-get clean \
|
&& apt-get clean \
|
||||||
&& rm -rf /var/lib/apt/lists/*
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ from functools import wraps
|
|||||||
from dotenv import load_dotenv
|
from dotenv import load_dotenv
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
|
from zoneinfo import ZoneInfo
|
||||||
import io
|
import io
|
||||||
import subprocess
|
import subprocess
|
||||||
import gzip
|
import gzip
|
||||||
@@ -72,7 +73,7 @@ def login_required(f):
|
|||||||
# Prüfe ob Session abgelaufen ist
|
# Prüfe ob Session abgelaufen ist
|
||||||
if 'last_activity' in session:
|
if 'last_activity' in session:
|
||||||
last_activity = datetime.fromisoformat(session['last_activity'])
|
last_activity = datetime.fromisoformat(session['last_activity'])
|
||||||
time_since_activity = datetime.now() - last_activity
|
time_since_activity = datetime.now(ZoneInfo("Europe/Berlin")).replace(tzinfo=None) - last_activity
|
||||||
|
|
||||||
# Debug-Logging
|
# Debug-Logging
|
||||||
app.logger.info(f"Session check for {session.get('username', 'unknown')}: "
|
app.logger.info(f"Session check for {session.get('username', 'unknown')}: "
|
||||||
@@ -170,7 +171,7 @@ def get_or_create_encryption_key():
|
|||||||
def create_backup(backup_type="manual", created_by=None):
|
def create_backup(backup_type="manual", created_by=None):
|
||||||
"""Erstellt ein verschlüsseltes Backup der Datenbank"""
|
"""Erstellt ein verschlüsseltes Backup der Datenbank"""
|
||||||
start_time = time.time()
|
start_time = time.time()
|
||||||
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
|
timestamp = datetime.now(ZoneInfo("Europe/Berlin")).strftime("%Y%m%d_%H%M%S")
|
||||||
filename = f"backup_v2docker_{timestamp}_encrypted.sql.gz.enc"
|
filename = f"backup_v2docker_{timestamp}_encrypted.sql.gz.enc"
|
||||||
filepath = BACKUP_DIR / filename
|
filepath = BACKUP_DIR / filename
|
||||||
|
|
||||||
@@ -398,7 +399,7 @@ def check_ip_blocked(ip_address):
|
|||||||
conn.close()
|
conn.close()
|
||||||
|
|
||||||
if result and result[0]:
|
if result and result[0]:
|
||||||
if result[0] > datetime.now():
|
if result[0] > datetime.now(ZoneInfo("Europe/Berlin")).replace(tzinfo=None):
|
||||||
return True, result[0]
|
return True, result[0]
|
||||||
return False, None
|
return False, None
|
||||||
|
|
||||||
@@ -425,7 +426,7 @@ def record_failed_attempt(ip_address, username):
|
|||||||
blocked_until = None
|
blocked_until = None
|
||||||
|
|
||||||
if new_count >= MAX_LOGIN_ATTEMPTS:
|
if new_count >= MAX_LOGIN_ATTEMPTS:
|
||||||
blocked_until = datetime.now() + timedelta(hours=BLOCK_DURATION_HOURS)
|
blocked_until = datetime.now(ZoneInfo("Europe/Berlin")).replace(tzinfo=None) + timedelta(hours=BLOCK_DURATION_HOURS)
|
||||||
# E-Mail-Benachrichtigung (wenn aktiviert)
|
# E-Mail-Benachrichtigung (wenn aktiviert)
|
||||||
if os.getenv("EMAIL_ENABLED", "false").lower() == "true":
|
if os.getenv("EMAIL_ENABLED", "false").lower() == "true":
|
||||||
send_security_alert_email(ip_address, username, new_count)
|
send_security_alert_email(ip_address, username, new_count)
|
||||||
@@ -505,7 +506,7 @@ def send_security_alert_email(ip_address, username, attempt_count):
|
|||||||
IP-Adresse: {ip_address}
|
IP-Adresse: {ip_address}
|
||||||
Versuchter Benutzername: {username}
|
Versuchter Benutzername: {username}
|
||||||
Anzahl Versuche: {attempt_count}
|
Anzahl Versuche: {attempt_count}
|
||||||
Zeit: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}
|
Zeit: {datetime.now(ZoneInfo("Europe/Berlin")).strftime('%Y-%m-%d %H:%M:%S')}
|
||||||
|
|
||||||
Die IP-Adresse wurde für 24 Stunden gesperrt.
|
Die IP-Adresse wurde für 24 Stunden gesperrt.
|
||||||
|
|
||||||
@@ -565,7 +566,7 @@ def generate_license_key(license_type='full'):
|
|||||||
chars = 'ABCDEFGHJKLMNPQRSTUVWXYZ23456789'
|
chars = 'ABCDEFGHJKLMNPQRSTUVWXYZ23456789'
|
||||||
|
|
||||||
# Datum-Teil
|
# Datum-Teil
|
||||||
now = datetime.now()
|
now = datetime.now(ZoneInfo("Europe/Berlin"))
|
||||||
date_part = now.strftime('%Y%m')
|
date_part = now.strftime('%Y%m')
|
||||||
type_char = 'F' if license_type == 'full' else 'T'
|
type_char = 'F' if license_type == 'full' else 'T'
|
||||||
|
|
||||||
@@ -606,7 +607,7 @@ def login():
|
|||||||
# Prüfen ob IP gesperrt ist
|
# Prüfen ob IP gesperrt ist
|
||||||
is_blocked, blocked_until = check_ip_blocked(ip_address)
|
is_blocked, blocked_until = check_ip_blocked(ip_address)
|
||||||
if is_blocked:
|
if is_blocked:
|
||||||
time_remaining = (blocked_until - datetime.now()).total_seconds() / 3600
|
time_remaining = (blocked_until - datetime.now(ZoneInfo("Europe/Berlin")).replace(tzinfo=None)).total_seconds() / 3600
|
||||||
error_msg = f"IP GESPERRT! Noch {time_remaining:.1f} Stunden warten."
|
error_msg = f"IP GESPERRT! Noch {time_remaining:.1f} Stunden warten."
|
||||||
return render_template("login.html", error=error_msg, error_type="blocked")
|
return render_template("login.html", error=error_msg, error_type="blocked")
|
||||||
|
|
||||||
@@ -668,7 +669,7 @@ def login():
|
|||||||
session.permanent = True # Aktiviert das Timeout
|
session.permanent = True # Aktiviert das Timeout
|
||||||
session['logged_in'] = True
|
session['logged_in'] = True
|
||||||
session['username'] = username
|
session['username'] = username
|
||||||
session['last_activity'] = datetime.now().isoformat()
|
session['last_activity'] = datetime.now(ZoneInfo("Europe/Berlin")).replace(tzinfo=None).isoformat()
|
||||||
reset_login_attempts(ip_address)
|
reset_login_attempts(ip_address)
|
||||||
log_audit('LOGIN_SUCCESS', 'user',
|
log_audit('LOGIN_SUCCESS', 'user',
|
||||||
additional_info=f"Erfolgreiche Anmeldung von IP: {ip_address}")
|
additional_info=f"Erfolgreiche Anmeldung von IP: {ip_address}")
|
||||||
@@ -710,7 +711,7 @@ def logout():
|
|||||||
def heartbeat():
|
def heartbeat():
|
||||||
"""Endpoint für Session Keep-Alive - aktualisiert last_activity"""
|
"""Endpoint für Session Keep-Alive - aktualisiert last_activity"""
|
||||||
# Aktualisiere last_activity nur wenn explizit angefordert
|
# Aktualisiere last_activity nur wenn explizit angefordert
|
||||||
session['last_activity'] = datetime.now().isoformat()
|
session['last_activity'] = datetime.now(ZoneInfo("Europe/Berlin")).replace(tzinfo=None).isoformat()
|
||||||
# Force session save
|
# Force session save
|
||||||
session.modified = True
|
session.modified = True
|
||||||
|
|
||||||
@@ -975,7 +976,7 @@ def dashboard():
|
|||||||
'ip_address': event[0],
|
'ip_address': event[0],
|
||||||
'attempt_count': event[1],
|
'attempt_count': event[1],
|
||||||
'last_attempt': event[2].strftime('%d.%m %H:%M'),
|
'last_attempt': event[2].strftime('%d.%m %H:%M'),
|
||||||
'blocked_until': event[3].strftime('%d.%m %H:%M') if event[3] and event[3] > datetime.now() else None,
|
'blocked_until': event[3].strftime('%d.%m %H:%M') if event[3] and event[3] > datetime.now(ZoneInfo("Europe/Berlin")).replace(tzinfo=None) else None,
|
||||||
'username_tried': event[4],
|
'username_tried': event[4],
|
||||||
'error_message': event[5]
|
'error_message': event[5]
|
||||||
})
|
})
|
||||||
@@ -1249,7 +1250,7 @@ def batch_licenses():
|
|||||||
'licenses': generated_licenses,
|
'licenses': generated_licenses,
|
||||||
'valid_from': valid_from,
|
'valid_from': valid_from,
|
||||||
'valid_until': valid_until,
|
'valid_until': valid_until,
|
||||||
'timestamp': datetime.now().isoformat()
|
'timestamp': datetime.now(ZoneInfo("Europe/Berlin")).replace(tzinfo=None).isoformat()
|
||||||
}
|
}
|
||||||
|
|
||||||
flash(f'{quantity} Lizenzen erfolgreich generiert!', 'success')
|
flash(f'{quantity} Lizenzen erfolgreich generiert!', 'success')
|
||||||
@@ -1308,7 +1309,7 @@ def export_batch():
|
|||||||
io.BytesIO(output.getvalue().encode('utf-8-sig')),
|
io.BytesIO(output.getvalue().encode('utf-8-sig')),
|
||||||
mimetype='text/csv',
|
mimetype='text/csv',
|
||||||
as_attachment=True,
|
as_attachment=True,
|
||||||
download_name=f"batch_licenses_{batch_data['customer'].replace(' ', '_')}_{datetime.now().strftime('%Y%m%d_%H%M%S')}.csv"
|
download_name=f"batch_licenses_{batch_data['customer'].replace(' ', '_')}_{datetime.now(ZoneInfo('Europe/Berlin')).strftime('%Y%m%d_%H%M%S')}.csv"
|
||||||
)
|
)
|
||||||
|
|
||||||
@app.route("/licenses")
|
@app.route("/licenses")
|
||||||
@@ -1778,7 +1779,7 @@ def export_licenses():
|
|||||||
# Audit-Log
|
# Audit-Log
|
||||||
log_audit('EXPORT', 'license',
|
log_audit('EXPORT', 'license',
|
||||||
additional_info=f"Export aller Lizenzen als {export_format.upper()}")
|
additional_info=f"Export aller Lizenzen als {export_format.upper()}")
|
||||||
filename = f'lizenzen_export_{datetime.now().strftime("%Y%m%d_%H%M%S")}'
|
filename = f'lizenzen_export_{datetime.now(ZoneInfo("Europe/Berlin")).strftime("%Y%m%d_%H%M%S")}'
|
||||||
|
|
||||||
if export_format == 'csv':
|
if export_format == 'csv':
|
||||||
# CSV Export
|
# CSV Export
|
||||||
@@ -1859,7 +1860,7 @@ def export_customers():
|
|||||||
# Audit-Log
|
# Audit-Log
|
||||||
log_audit('EXPORT', 'customer',
|
log_audit('EXPORT', 'customer',
|
||||||
additional_info=f"Export aller Kunden als {export_format.upper()}")
|
additional_info=f"Export aller Kunden als {export_format.upper()}")
|
||||||
filename = f'kunden_export_{datetime.now().strftime("%Y%m%d_%H%M%S")}'
|
filename = f'kunden_export_{datetime.now(ZoneInfo("Europe/Berlin")).strftime("%Y%m%d_%H%M%S")}'
|
||||||
|
|
||||||
if export_format == 'csv':
|
if export_format == 'csv':
|
||||||
# CSV Export
|
# CSV Export
|
||||||
@@ -2108,7 +2109,7 @@ def blocked_ips():
|
|||||||
'first_attempt': ip[2].strftime('%d.%m.%Y %H:%M'),
|
'first_attempt': ip[2].strftime('%d.%m.%Y %H:%M'),
|
||||||
'last_attempt': ip[3].strftime('%d.%m.%Y %H:%M'),
|
'last_attempt': ip[3].strftime('%d.%m.%Y %H:%M'),
|
||||||
'blocked_until': ip[4].strftime('%d.%m.%Y %H:%M'),
|
'blocked_until': ip[4].strftime('%d.%m.%Y %H:%M'),
|
||||||
'is_active': ip[4] > datetime.now(),
|
'is_active': ip[4] > datetime.now(ZoneInfo("Europe/Berlin")).replace(tzinfo=None),
|
||||||
'last_username': ip[5],
|
'last_username': ip[5],
|
||||||
'last_error': ip[6]
|
'last_error': ip[6]
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,11 +1,14 @@
|
|||||||
-- UTF-8 Encoding für deutsche Sonderzeichen sicherstellen
|
-- UTF-8 Encoding für deutsche Sonderzeichen sicherstellen
|
||||||
SET client_encoding = 'UTF8';
|
SET client_encoding = 'UTF8';
|
||||||
|
|
||||||
|
-- Zeitzone auf Europe/Berlin setzen
|
||||||
|
SET timezone = 'Europe/Berlin';
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS customers (
|
CREATE TABLE IF NOT EXISTS customers (
|
||||||
id SERIAL PRIMARY KEY,
|
id SERIAL PRIMARY KEY,
|
||||||
name TEXT NOT NULL,
|
name TEXT NOT NULL,
|
||||||
email TEXT,
|
email TEXT,
|
||||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
||||||
CONSTRAINT unique_email UNIQUE (email)
|
CONSTRAINT unique_email UNIQUE (email)
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -17,7 +20,7 @@ CREATE TABLE IF NOT EXISTS licenses (
|
|||||||
valid_from DATE NOT NULL,
|
valid_from DATE NOT NULL,
|
||||||
valid_until DATE NOT NULL,
|
valid_until DATE NOT NULL,
|
||||||
is_active BOOLEAN DEFAULT TRUE,
|
is_active BOOLEAN DEFAULT TRUE,
|
||||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS sessions (
|
CREATE TABLE IF NOT EXISTS sessions (
|
||||||
@@ -26,16 +29,16 @@ CREATE TABLE IF NOT EXISTS sessions (
|
|||||||
session_id TEXT UNIQUE NOT NULL,
|
session_id TEXT UNIQUE NOT NULL,
|
||||||
ip_address TEXT,
|
ip_address TEXT,
|
||||||
user_agent TEXT,
|
user_agent TEXT,
|
||||||
started_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
started_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
||||||
last_heartbeat TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
last_heartbeat TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
||||||
ended_at TIMESTAMP,
|
ended_at TIMESTAMP WITH TIME ZONE,
|
||||||
is_active BOOLEAN DEFAULT TRUE
|
is_active BOOLEAN DEFAULT TRUE
|
||||||
);
|
);
|
||||||
|
|
||||||
-- Audit-Log-Tabelle für Änderungsprotokolle
|
-- Audit-Log-Tabelle für Änderungsprotokolle
|
||||||
CREATE TABLE IF NOT EXISTS audit_log (
|
CREATE TABLE IF NOT EXISTS audit_log (
|
||||||
id SERIAL PRIMARY KEY,
|
id SERIAL PRIMARY KEY,
|
||||||
timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
timestamp TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
||||||
username TEXT NOT NULL,
|
username TEXT NOT NULL,
|
||||||
action TEXT NOT NULL,
|
action TEXT NOT NULL,
|
||||||
entity_type TEXT NOT NULL,
|
entity_type TEXT NOT NULL,
|
||||||
@@ -61,7 +64,7 @@ CREATE TABLE IF NOT EXISTS backup_history (
|
|||||||
backup_type TEXT NOT NULL, -- 'manual' oder 'scheduled'
|
backup_type TEXT NOT NULL, -- 'manual' oder 'scheduled'
|
||||||
status TEXT NOT NULL, -- 'success', 'failed', 'in_progress'
|
status TEXT NOT NULL, -- 'success', 'failed', 'in_progress'
|
||||||
error_message TEXT,
|
error_message TEXT,
|
||||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
||||||
created_by TEXT NOT NULL,
|
created_by TEXT NOT NULL,
|
||||||
tables_count INTEGER,
|
tables_count INTEGER,
|
||||||
records_count INTEGER,
|
records_count INTEGER,
|
||||||
@@ -77,9 +80,9 @@ CREATE INDEX idx_backup_history_status ON backup_history(status);
|
|||||||
CREATE TABLE IF NOT EXISTS login_attempts (
|
CREATE TABLE IF NOT EXISTS login_attempts (
|
||||||
ip_address VARCHAR(45) PRIMARY KEY,
|
ip_address VARCHAR(45) PRIMARY KEY,
|
||||||
attempt_count INTEGER DEFAULT 0,
|
attempt_count INTEGER DEFAULT 0,
|
||||||
first_attempt TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
first_attempt TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
||||||
last_attempt TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
last_attempt TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
||||||
blocked_until TIMESTAMP NULL,
|
blocked_until TIMESTAMP WITH TIME ZONE NULL,
|
||||||
last_username_tried TEXT,
|
last_username_tried TEXT,
|
||||||
last_error_message TEXT
|
last_error_message TEXT
|
||||||
);
|
);
|
||||||
@@ -93,7 +96,7 @@ DO $$
|
|||||||
BEGIN
|
BEGIN
|
||||||
IF NOT EXISTS (SELECT 1 FROM information_schema.columns
|
IF NOT EXISTS (SELECT 1 FROM information_schema.columns
|
||||||
WHERE table_name = 'licenses' AND column_name = 'created_at') THEN
|
WHERE table_name = 'licenses' AND column_name = 'created_at') THEN
|
||||||
ALTER TABLE licenses ADD COLUMN created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP;
|
ALTER TABLE licenses ADD COLUMN created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP;
|
||||||
|
|
||||||
-- Setze created_at für bestehende Einträge auf das valid_from Datum
|
-- Setze created_at für bestehende Einträge auf das valid_from Datum
|
||||||
UPDATE licenses SET created_at = valid_from WHERE created_at IS NULL;
|
UPDATE licenses SET created_at = valid_from WHERE created_at IS NULL;
|
||||||
|
|||||||
@@ -1,5 +1,15 @@
|
|||||||
FROM python:3.11-slim
|
FROM python:3.11-slim
|
||||||
|
|
||||||
|
# Zeitzone setzen
|
||||||
|
ENV TZ=Europe/Berlin
|
||||||
|
ENV DEBIAN_FRONTEND=noninteractive
|
||||||
|
|
||||||
|
RUN apt-get update && apt-get install -y tzdata \
|
||||||
|
&& ln -sf /usr/share/zoneinfo/Europe/Berlin /etc/localtime \
|
||||||
|
&& echo "Europe/Berlin" > /etc/timezone \
|
||||||
|
&& apt-get clean \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
# Placeholder für Lizenzserver
|
# Placeholder für Lizenzserver
|
||||||
|
|||||||
@@ -1,5 +1,11 @@
|
|||||||
FROM nginx:alpine
|
FROM nginx:alpine
|
||||||
|
|
||||||
|
# Zeitzone setzen
|
||||||
|
ENV TZ=Europe/Berlin
|
||||||
|
RUN apk add --no-cache tzdata \
|
||||||
|
&& ln -sf /usr/share/zoneinfo/Europe/Berlin /etc/localtime \
|
||||||
|
&& echo "Europe/Berlin" > /etc/timezone
|
||||||
|
|
||||||
# SSL-Verzeichnis erstellen
|
# SSL-Verzeichnis erstellen
|
||||||
RUN mkdir -p /etc/nginx/ssl
|
RUN mkdir -p /etc/nginx/ssl
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
FROM postgres:14
|
FROM postgres:14
|
||||||
|
|
||||||
# Deutsche Locale installieren
|
# Deutsche Locale und Zeitzone installieren
|
||||||
RUN apt-get update && apt-get install -y locales \
|
RUN apt-get update && apt-get install -y locales tzdata \
|
||||||
&& sed -i '/de_DE.UTF-8/s/^# //g' /etc/locale.gen \
|
&& sed -i '/de_DE.UTF-8/s/^# //g' /etc/locale.gen \
|
||||||
&& locale-gen \
|
&& locale-gen \
|
||||||
&& update-locale LANG=de_DE.UTF-8 \
|
&& update-locale LANG=de_DE.UTF-8 \
|
||||||
|
&& ln -sf /usr/share/zoneinfo/Europe/Berlin /etc/localtime \
|
||||||
|
&& echo "Europe/Berlin" > /etc/timezone \
|
||||||
&& apt-get clean \
|
&& apt-get clean \
|
||||||
&& rm -rf /var/lib/apt/lists/*
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
@@ -12,3 +14,7 @@ RUN apt-get update && apt-get install -y locales \
|
|||||||
ENV LANG de_DE.UTF-8
|
ENV LANG de_DE.UTF-8
|
||||||
ENV LANGUAGE de_DE:de
|
ENV LANGUAGE de_DE:de
|
||||||
ENV LC_ALL de_DE.UTF-8
|
ENV LC_ALL de_DE.UTF-8
|
||||||
|
|
||||||
|
# Zeitzone setzen
|
||||||
|
ENV TZ=Europe/Berlin
|
||||||
|
ENV PGTZ=Europe/Berlin
|
||||||
10
v2_testing/.claude/settings.local.json
Normale Datei
10
v2_testing/.claude/settings.local.json
Normale Datei
@@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"permissions": {
|
||||||
|
"allow": [
|
||||||
|
"Bash(python3:*)",
|
||||||
|
"Bash(pip install:*)",
|
||||||
|
"Bash(pip3 install:*)"
|
||||||
|
],
|
||||||
|
"deny": []
|
||||||
|
}
|
||||||
|
}
|
||||||
104
v2_testing/test_audit_raw.py
Normale Datei
104
v2_testing/test_audit_raw.py
Normale Datei
@@ -0,0 +1,104 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
import requests
|
||||||
|
import urllib3
|
||||||
|
from datetime import datetime
|
||||||
|
from zoneinfo import ZoneInfo
|
||||||
|
from bs4 import BeautifulSoup
|
||||||
|
import time
|
||||||
|
|
||||||
|
# Disable SSL warnings for self-signed certificate
|
||||||
|
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
|
||||||
|
|
||||||
|
# Test configuration
|
||||||
|
base_url = "https://admin-panel-undso.z5m7q9dk3ah2v1plx6ju.com"
|
||||||
|
fallback_url = "https://localhost:443"
|
||||||
|
admin_user = {"username": "rac00n", "password": "1248163264"}
|
||||||
|
|
||||||
|
def test_audit_raw():
|
||||||
|
"""Test audit log timezone by parsing HTML"""
|
||||||
|
session = requests.Session()
|
||||||
|
|
||||||
|
print("Audit Log Raw HTML Test")
|
||||||
|
print("=" * 50)
|
||||||
|
|
||||||
|
# Test connection
|
||||||
|
try:
|
||||||
|
test_response = session.get(base_url, verify=True, timeout=5)
|
||||||
|
verify_ssl = True
|
||||||
|
base_url_local = base_url
|
||||||
|
print(f"✓ Using external URL: {base_url}")
|
||||||
|
except:
|
||||||
|
base_url_local = fallback_url
|
||||||
|
verify_ssl = False
|
||||||
|
print(f"ℹ Using fallback URL: {fallback_url}")
|
||||||
|
|
||||||
|
# Show current times
|
||||||
|
utc_now = datetime.now(ZoneInfo("UTC"))
|
||||||
|
berlin_now = datetime.now(ZoneInfo("Europe/Berlin"))
|
||||||
|
|
||||||
|
print(f"\nCurrent times:")
|
||||||
|
print(f" UTC: {utc_now.strftime('%Y-%m-%d %H:%M:%S')}")
|
||||||
|
print(f" Berlin: {berlin_now.strftime('%Y-%m-%d %H:%M:%S')}")
|
||||||
|
|
||||||
|
# Logout first
|
||||||
|
session.get(f"{base_url_local}/logout", verify=verify_ssl)
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
# Login
|
||||||
|
response = session.get(f"{base_url_local}/login", verify=verify_ssl)
|
||||||
|
login_data = {
|
||||||
|
"username": admin_user["username"],
|
||||||
|
"password": admin_user["password"]
|
||||||
|
}
|
||||||
|
response = session.post(f"{base_url_local}/login", data=login_data, verify=verify_ssl, allow_redirects=False)
|
||||||
|
|
||||||
|
if response.status_code != 302:
|
||||||
|
print(f"✗ Login failed")
|
||||||
|
return
|
||||||
|
|
||||||
|
print("✓ Login successful")
|
||||||
|
|
||||||
|
# Get audit log
|
||||||
|
print("\nFetching audit log...")
|
||||||
|
response = session.get(f"{base_url_local}/audit", verify=verify_ssl)
|
||||||
|
|
||||||
|
if response.status_code == 200:
|
||||||
|
# Save raw HTML for inspection
|
||||||
|
with open("audit_log_raw.html", "w", encoding="utf-8") as f:
|
||||||
|
f.write(response.text)
|
||||||
|
print("✓ Saved raw HTML to audit_log_raw.html")
|
||||||
|
|
||||||
|
# Parse with BeautifulSoup
|
||||||
|
soup = BeautifulSoup(response.text, 'html.parser')
|
||||||
|
|
||||||
|
# Find all table rows
|
||||||
|
rows = soup.find_all('tr')
|
||||||
|
print(f"✓ Found {len(rows)} table rows")
|
||||||
|
|
||||||
|
# Look for LOGIN_SUCCESS in recent entries
|
||||||
|
for i, row in enumerate(rows[:5]): # Check first 5 rows
|
||||||
|
cells = row.find_all('td')
|
||||||
|
if cells and len(cells) > 1:
|
||||||
|
timestamp_cell = cells[0].text.strip()
|
||||||
|
action_cell = cells[2].text.strip() if len(cells) > 2 else ""
|
||||||
|
|
||||||
|
if i == 0:
|
||||||
|
print(f"\nFirst row details:")
|
||||||
|
print(f" Timestamp: {timestamp_cell}")
|
||||||
|
print(f" Action: {action_cell}")
|
||||||
|
|
||||||
|
if "LOGIN_SUCCESS" in action_cell:
|
||||||
|
print(f"\nFound LOGIN_SUCCESS entry:")
|
||||||
|
print(f" Timestamp: {timestamp_cell}")
|
||||||
|
|
||||||
|
# Check if timestamp contains current Berlin hour
|
||||||
|
if berlin_now.strftime("%H:") in timestamp_cell:
|
||||||
|
print(f" ✓ Contains Berlin hour ({berlin_now.strftime('%H:')})")
|
||||||
|
elif utc_now.strftime("%H:") in timestamp_cell:
|
||||||
|
print(f" ✗ Contains UTC hour ({utc_now.strftime('%H:')})")
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
print(f"✗ Failed to fetch audit log: {response.status_code}")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
test_audit_raw()
|
||||||
113
v2_testing/test_audit_simple.py
Normale Datei
113
v2_testing/test_audit_simple.py
Normale Datei
@@ -0,0 +1,113 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
import requests
|
||||||
|
import urllib3
|
||||||
|
from datetime import datetime
|
||||||
|
from zoneinfo import ZoneInfo
|
||||||
|
import time
|
||||||
|
import re
|
||||||
|
|
||||||
|
# Disable SSL warnings for self-signed certificate
|
||||||
|
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
|
||||||
|
|
||||||
|
# Test configuration
|
||||||
|
base_url = "https://admin-panel-undso.z5m7q9dk3ah2v1plx6ju.com"
|
||||||
|
fallback_url = "https://localhost:443"
|
||||||
|
admin_user = {"username": "rac00n", "password": "1248163264"}
|
||||||
|
|
||||||
|
def test_audit_simple():
|
||||||
|
"""Simple test to check audit log timestamps"""
|
||||||
|
session = requests.Session()
|
||||||
|
|
||||||
|
print("Audit Log Timezone Check")
|
||||||
|
print("=" * 50)
|
||||||
|
|
||||||
|
# Test connection
|
||||||
|
try:
|
||||||
|
test_response = session.get(base_url, verify=True, timeout=5)
|
||||||
|
verify_ssl = True
|
||||||
|
base_url_local = base_url
|
||||||
|
print(f"✓ Using external URL: {base_url}")
|
||||||
|
except:
|
||||||
|
base_url_local = fallback_url
|
||||||
|
verify_ssl = False
|
||||||
|
print(f"ℹ Using fallback URL: {fallback_url}")
|
||||||
|
|
||||||
|
# Show current times
|
||||||
|
utc_now = datetime.now(ZoneInfo("UTC"))
|
||||||
|
berlin_now = datetime.now(ZoneInfo("Europe/Berlin"))
|
||||||
|
|
||||||
|
print(f"\nCurrent times:")
|
||||||
|
print(f" UTC: {utc_now.strftime('%Y-%m-%d %H:%M:%S')}")
|
||||||
|
print(f" Berlin: {berlin_now.strftime('%Y-%m-%d %H:%M:%S')}")
|
||||||
|
print(f" Difference: {(berlin_now.hour - utc_now.hour) % 24} hours")
|
||||||
|
|
||||||
|
# Login
|
||||||
|
response = session.get(f"{base_url_local}/login", verify=verify_ssl)
|
||||||
|
login_data = {
|
||||||
|
"username": admin_user["username"],
|
||||||
|
"password": admin_user["password"]
|
||||||
|
}
|
||||||
|
response = session.post(f"{base_url_local}/login", data=login_data, verify=verify_ssl, allow_redirects=False)
|
||||||
|
|
||||||
|
if response.status_code != 302:
|
||||||
|
print(f"✗ Login failed")
|
||||||
|
return
|
||||||
|
|
||||||
|
print("✓ Login successful")
|
||||||
|
|
||||||
|
# Create a distinctive action to find in audit log
|
||||||
|
print("\nCreating a test action...")
|
||||||
|
|
||||||
|
# Try to access customers page (this will create an audit entry)
|
||||||
|
response = session.get(f"{base_url_local}/customers", verify=verify_ssl)
|
||||||
|
|
||||||
|
# Now check audit log
|
||||||
|
print("\nChecking audit log...")
|
||||||
|
response = session.get(f"{base_url_local}/audit", verify=verify_ssl)
|
||||||
|
|
||||||
|
if response.status_code == 200:
|
||||||
|
# Look for table rows with class="table"
|
||||||
|
# Extract just the table content
|
||||||
|
table_match = re.search(r'<table class="table[^>]*>(.*?)</table>', response.text, re.DOTALL)
|
||||||
|
|
||||||
|
if table_match:
|
||||||
|
table_content = table_match.group(1)
|
||||||
|
|
||||||
|
# Find all <tr> tags
|
||||||
|
rows = re.findall(r'<tr[^>]*>(.*?)</tr>', table_content, re.DOTALL)
|
||||||
|
|
||||||
|
print(f"✓ Found {len(rows)} audit log entries")
|
||||||
|
|
||||||
|
if rows:
|
||||||
|
# Get the first data row (skip header)
|
||||||
|
first_row = rows[1] if len(rows) > 1 else rows[0]
|
||||||
|
|
||||||
|
# Extract timestamp from first cell
|
||||||
|
timestamp_match = re.search(r'<td[^>]*>([^<]+)</td>', first_row)
|
||||||
|
|
||||||
|
if timestamp_match:
|
||||||
|
timestamp = timestamp_match.group(1).strip()
|
||||||
|
print(f"\nMost recent audit entry timestamp: {timestamp}")
|
||||||
|
|
||||||
|
# Check if it contains current Berlin hour
|
||||||
|
berlin_hour = berlin_now.strftime("%H:")
|
||||||
|
utc_hour = utc_now.strftime("%H:")
|
||||||
|
|
||||||
|
if berlin_hour in timestamp:
|
||||||
|
print(f"✓ Timestamp contains Berlin hour ({berlin_hour})")
|
||||||
|
print("✓ Audit log is using Berlin timezone!")
|
||||||
|
elif utc_hour in timestamp:
|
||||||
|
print(f"✗ Timestamp contains UTC hour ({utc_hour})")
|
||||||
|
print("✗ Audit log is still using UTC")
|
||||||
|
print("\nTo fix this:")
|
||||||
|
print("1. cd ../v2")
|
||||||
|
print("2. docker-compose down")
|
||||||
|
print("3. docker-compose build --no-cache")
|
||||||
|
print("4. docker-compose up -d")
|
||||||
|
else:
|
||||||
|
print("⚠ Could not determine timezone from timestamp")
|
||||||
|
else:
|
||||||
|
print(f"✗ Failed to fetch audit log: {response.status_code}")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
test_audit_simple()
|
||||||
123
v2_testing/test_audit_timezone.py
Normale Datei
123
v2_testing/test_audit_timezone.py
Normale Datei
@@ -0,0 +1,123 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
import requests
|
||||||
|
import urllib3
|
||||||
|
from datetime import datetime
|
||||||
|
from zoneinfo import ZoneInfo
|
||||||
|
import time
|
||||||
|
import re
|
||||||
|
|
||||||
|
# Disable SSL warnings for self-signed certificate
|
||||||
|
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
|
||||||
|
|
||||||
|
# Test configuration
|
||||||
|
base_url = "https://admin-panel-undso.z5m7q9dk3ah2v1plx6ju.com"
|
||||||
|
fallback_url = "https://localhost:443"
|
||||||
|
admin_user = {"username": "rac00n", "password": "1248163264"}
|
||||||
|
|
||||||
|
def test_audit_timezone():
|
||||||
|
"""Test audit log timezone specifically"""
|
||||||
|
session = requests.Session()
|
||||||
|
|
||||||
|
print("Audit Log Timezone Test")
|
||||||
|
print("=" * 50)
|
||||||
|
|
||||||
|
# Test connection
|
||||||
|
try:
|
||||||
|
test_response = session.get(base_url, verify=True, timeout=5)
|
||||||
|
verify_ssl = True
|
||||||
|
base_url_local = base_url
|
||||||
|
print(f"✓ Using external URL: {base_url}")
|
||||||
|
except:
|
||||||
|
base_url_local = fallback_url
|
||||||
|
verify_ssl = False
|
||||||
|
print(f"ℹ Using fallback URL: {fallback_url}")
|
||||||
|
|
||||||
|
# Show current times
|
||||||
|
utc_now = datetime.now(ZoneInfo("UTC"))
|
||||||
|
berlin_now = datetime.now(ZoneInfo("Europe/Berlin"))
|
||||||
|
|
||||||
|
print(f"\nCurrent times:")
|
||||||
|
print(f" UTC: {utc_now.strftime('%Y-%m-%d %H:%M:%S')}")
|
||||||
|
print(f" Berlin: {berlin_now.strftime('%Y-%m-%d %H:%M:%S')}")
|
||||||
|
print(f" Offset: +{(berlin_now.hour - utc_now.hour) % 24} hours")
|
||||||
|
|
||||||
|
# First logout if already logged in
|
||||||
|
session.get(f"{base_url_local}/logout", verify=verify_ssl)
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
# Login (this will create a new audit log entry)
|
||||||
|
print(f"\nPerforming login at {berlin_now.strftime('%H:%M:%S')} Berlin time...")
|
||||||
|
|
||||||
|
response = session.get(f"{base_url_local}/login", verify=verify_ssl)
|
||||||
|
if response.status_code != 200:
|
||||||
|
print(f"✗ Failed to access login page: {response.status_code}")
|
||||||
|
return
|
||||||
|
|
||||||
|
login_data = {
|
||||||
|
"username": admin_user["username"],
|
||||||
|
"password": admin_user["password"]
|
||||||
|
}
|
||||||
|
|
||||||
|
response = session.post(f"{base_url_local}/login", data=login_data, verify=verify_ssl, allow_redirects=False)
|
||||||
|
|
||||||
|
if response.status_code != 302:
|
||||||
|
print(f"✗ Login failed: {response.status_code}")
|
||||||
|
return
|
||||||
|
|
||||||
|
print("✓ Login successful")
|
||||||
|
|
||||||
|
# Immediately check audit log
|
||||||
|
print("\nChecking audit log for fresh LOGIN_SUCCESS entry...")
|
||||||
|
response = session.get(f"{base_url_local}/audit", verify=verify_ssl)
|
||||||
|
|
||||||
|
if response.status_code == 200:
|
||||||
|
# Look for timestamps in the audit log
|
||||||
|
# Pattern to find timestamps in format YYYY-MM-DD HH:MM:SS
|
||||||
|
timestamp_pattern = r'(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})'
|
||||||
|
|
||||||
|
# Find all timestamps
|
||||||
|
timestamps = re.findall(timestamp_pattern, response.text)
|
||||||
|
|
||||||
|
if timestamps:
|
||||||
|
print(f"✓ Found {len(timestamps)} timestamps in audit log")
|
||||||
|
|
||||||
|
# Check the most recent timestamp (should be first in list)
|
||||||
|
if timestamps:
|
||||||
|
latest_timestamp = timestamps[0]
|
||||||
|
print(f"\nMost recent timestamp: {latest_timestamp}")
|
||||||
|
|
||||||
|
# Extract hour from timestamp
|
||||||
|
hour_match = re.search(r' (\d{2}):', latest_timestamp)
|
||||||
|
if hour_match:
|
||||||
|
log_hour = int(hour_match.group(1))
|
||||||
|
berlin_hour = berlin_now.hour
|
||||||
|
utc_hour = utc_now.hour
|
||||||
|
|
||||||
|
print(f" Timestamp hour: {log_hour:02d}")
|
||||||
|
print(f" Berlin hour: {berlin_hour:02d}")
|
||||||
|
print(f" UTC hour: {utc_hour:02d}")
|
||||||
|
|
||||||
|
if log_hour == berlin_hour:
|
||||||
|
print("\n✓ Audit log is using Berlin time!")
|
||||||
|
elif log_hour == utc_hour:
|
||||||
|
print("\n✗ Audit log appears to be using UTC time")
|
||||||
|
print(" → Docker containers may need to be rebuilt")
|
||||||
|
else:
|
||||||
|
print("\n⚠ Could not determine timezone (timestamp doesn't match either timezone)")
|
||||||
|
else:
|
||||||
|
print("✗ No timestamps found in audit log")
|
||||||
|
|
||||||
|
# Also check for "vor X Minuten" text which might indicate timezone
|
||||||
|
if "vor 0 Minuten" in response.text or "vor 1 Minute" in response.text:
|
||||||
|
print("\n✓ Recent entries found (German time format)")
|
||||||
|
else:
|
||||||
|
print(f"✗ Failed to access audit log: {response.status_code}")
|
||||||
|
|
||||||
|
print("\n" + "=" * 50)
|
||||||
|
print("If timestamps show UTC instead of Berlin time:")
|
||||||
|
print("1. Run: docker-compose down")
|
||||||
|
print("2. Run: docker-compose build --no-cache")
|
||||||
|
print("3. Run: docker-compose up -d")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
test_audit_timezone()
|
||||||
159
v2_testing/test_timezone.py
Normale Datei
159
v2_testing/test_timezone.py
Normale Datei
@@ -0,0 +1,159 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
import requests
|
||||||
|
import urllib3
|
||||||
|
from datetime import datetime
|
||||||
|
from zoneinfo import ZoneInfo
|
||||||
|
import json
|
||||||
|
import time
|
||||||
|
|
||||||
|
# Disable SSL warnings for self-signed certificate
|
||||||
|
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
|
||||||
|
|
||||||
|
# Test configuration
|
||||||
|
# Use external URL for testing
|
||||||
|
base_url = "https://admin-panel-undso.z5m7q9dk3ah2v1plx6ju.com"
|
||||||
|
# Fallback to localhost if external URL is not accessible
|
||||||
|
fallback_url = "https://localhost:443"
|
||||||
|
admin_user = {"username": "rac00n", "password": "1248163264"}
|
||||||
|
|
||||||
|
def test_timezone_functionality():
|
||||||
|
"""Test if timestamps are in German timezone (Europe/Berlin)"""
|
||||||
|
session = requests.Session()
|
||||||
|
|
||||||
|
print("Testing Timezone Functionality (Europe/Berlin)")
|
||||||
|
print("=" * 50)
|
||||||
|
|
||||||
|
# Test connection to external URL first
|
||||||
|
global base_url
|
||||||
|
try:
|
||||||
|
test_response = session.get(base_url, verify=True, timeout=5)
|
||||||
|
print(f"✓ Using external URL: {base_url}")
|
||||||
|
except:
|
||||||
|
base_url = fallback_url
|
||||||
|
print(f"ℹ Using fallback URL: {base_url}")
|
||||||
|
|
||||||
|
# Get current time in UTC and Berlin
|
||||||
|
utc_now = datetime.now(ZoneInfo("UTC"))
|
||||||
|
berlin_now = datetime.now(ZoneInfo("Europe/Berlin"))
|
||||||
|
|
||||||
|
print(f"Current UTC time: {utc_now.strftime('%Y-%m-%d %H:%M:%S %Z')}")
|
||||||
|
print(f"Current Berlin time: {berlin_now.strftime('%Y-%m-%d %H:%M:%S %Z')}")
|
||||||
|
print(f"Time difference: {(berlin_now.hour - utc_now.hour) % 24} hours")
|
||||||
|
print()
|
||||||
|
|
||||||
|
# Login
|
||||||
|
verify_ssl = base_url != fallback_url # Verify SSL for external URL only
|
||||||
|
response = session.get(f"{base_url}/login", verify=verify_ssl)
|
||||||
|
if response.status_code != 200:
|
||||||
|
print(f"✗ Failed to access login page: {response.status_code}")
|
||||||
|
return
|
||||||
|
|
||||||
|
login_data = {
|
||||||
|
"username": admin_user["username"],
|
||||||
|
"password": admin_user["password"]
|
||||||
|
}
|
||||||
|
|
||||||
|
response = session.post(f"{base_url}/login", data=login_data, verify=verify_ssl, allow_redirects=False)
|
||||||
|
|
||||||
|
if response.status_code != 302:
|
||||||
|
print(f"✗ Login failed: {response.status_code}")
|
||||||
|
return
|
||||||
|
|
||||||
|
print("✓ Login successful")
|
||||||
|
print()
|
||||||
|
|
||||||
|
# Test 1: Create a test license to check created_at timestamp
|
||||||
|
print("Test 1: Creating test license to check timestamps...")
|
||||||
|
|
||||||
|
# First, get a customer ID or create one
|
||||||
|
license_data = {
|
||||||
|
"customer_select": "new",
|
||||||
|
"customer_name": f"Timezone Test Customer {int(time.time())}",
|
||||||
|
"customer_email": f"timezone-test-{int(time.time())}@example.com",
|
||||||
|
"license_key": f"AF-{berlin_now.strftime('%Y%m')}T-TEST-TIME-ZONE",
|
||||||
|
"license_type": "test",
|
||||||
|
"max_sessions": "1",
|
||||||
|
"start_date": berlin_now.strftime("%Y-%m-%d"),
|
||||||
|
"duration": "1",
|
||||||
|
"duration_unit": "days"
|
||||||
|
}
|
||||||
|
|
||||||
|
response = session.post(f"{base_url}/create", data=license_data, verify=verify_ssl)
|
||||||
|
|
||||||
|
if response.status_code == 200:
|
||||||
|
print("✓ Test license created")
|
||||||
|
else:
|
||||||
|
print(f"✗ Failed to create license: {response.status_code}")
|
||||||
|
|
||||||
|
# Test 2: Check audit log for timezone
|
||||||
|
print("\nTest 2: Checking audit log timestamps...")
|
||||||
|
|
||||||
|
response = session.get(f"{base_url}/audit", verify=verify_ssl)
|
||||||
|
if response.status_code == 200:
|
||||||
|
# Extract the most recent audit log entry timestamp from HTML
|
||||||
|
if "CREATE" in response.text and license_data["license_key"] in response.text:
|
||||||
|
print("✓ Audit log entry created")
|
||||||
|
# Check if timestamps in audit log appear to be in German time
|
||||||
|
# This is a simple check - in production you'd parse the HTML properly
|
||||||
|
current_hour = berlin_now.strftime("%H:")
|
||||||
|
if current_hour in response.text:
|
||||||
|
print(f"✓ Audit log shows Berlin time (contains {current_hour})")
|
||||||
|
else:
|
||||||
|
print(f"⚠ Audit log might show UTC time (doesn't contain {current_hour})")
|
||||||
|
else:
|
||||||
|
print(f"✗ Failed to access audit log: {response.status_code}")
|
||||||
|
|
||||||
|
# Test 3: Check backup functionality for filename timezone
|
||||||
|
print("\nTest 3: Testing backup filename timezone...")
|
||||||
|
|
||||||
|
response = session.post(f"{base_url}/backup/create", verify=verify_ssl)
|
||||||
|
if response.status_code == 302: # Redirect after backup
|
||||||
|
print("✓ Backup created")
|
||||||
|
|
||||||
|
# Check backup list
|
||||||
|
response = session.get(f"{base_url}/backups", verify=verify_ssl)
|
||||||
|
if response.status_code == 200:
|
||||||
|
# Check if backup filename contains current Berlin hour
|
||||||
|
berlin_hour = berlin_now.strftime("%H")
|
||||||
|
if f"_{berlin_hour}" in response.text:
|
||||||
|
print(f"✓ Backup filename uses Berlin time (contains hour {berlin_hour})")
|
||||||
|
else:
|
||||||
|
utc_hour = utc_now.strftime("%H")
|
||||||
|
if f"_{utc_hour}" in response.text:
|
||||||
|
print(f"✗ Backup filename might use UTC time (contains hour {utc_hour})")
|
||||||
|
else:
|
||||||
|
print("⚠ Could not determine timezone from backup filename")
|
||||||
|
else:
|
||||||
|
print(f"✗ Failed to create backup: {response.status_code}")
|
||||||
|
|
||||||
|
# Test 4: Check session timestamps
|
||||||
|
print("\nTest 4: Checking session timestamps...")
|
||||||
|
|
||||||
|
response = session.get(f"{base_url}/sessions", verify=verify_ssl)
|
||||||
|
if response.status_code == 200:
|
||||||
|
print("✓ Accessed sessions page")
|
||||||
|
# Active sessions should show current time
|
||||||
|
if "Keine aktiven Sessions" not in response.text:
|
||||||
|
print("✓ Session data available")
|
||||||
|
else:
|
||||||
|
print("ℹ No active sessions to check (this is normal)")
|
||||||
|
else:
|
||||||
|
print(f"✗ Failed to access sessions: {response.status_code}")
|
||||||
|
|
||||||
|
# Test 5: Database timezone check
|
||||||
|
print("\nTest 5: Summary")
|
||||||
|
print("-" * 30)
|
||||||
|
|
||||||
|
time_diff = (berlin_now.hour - utc_now.hour) % 24
|
||||||
|
if time_diff == 1:
|
||||||
|
print("✓ Timezone offset is +1 hour (CET - Central European Time)")
|
||||||
|
elif time_diff == 2:
|
||||||
|
print("✓ Timezone offset is +2 hours (CEST - Central European Summer Time)")
|
||||||
|
else:
|
||||||
|
print(f"⚠ Unexpected timezone offset: {time_diff} hours")
|
||||||
|
|
||||||
|
print("\nNote: All new timestamps should be in Europe/Berlin timezone")
|
||||||
|
print("Existing data might still show UTC until updated")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
test_timezone_functionality()
|
||||||
122
v2_testing/test_timezone_simple.py
Normale Datei
122
v2_testing/test_timezone_simple.py
Normale Datei
@@ -0,0 +1,122 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
import requests
|
||||||
|
import urllib3
|
||||||
|
from datetime import datetime
|
||||||
|
from zoneinfo import ZoneInfo
|
||||||
|
import re
|
||||||
|
|
||||||
|
# Disable SSL warnings for self-signed certificate
|
||||||
|
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
|
||||||
|
|
||||||
|
# Test configuration
|
||||||
|
base_url = "https://admin-panel-undso.z5m7q9dk3ah2v1plx6ju.com"
|
||||||
|
fallback_url = "https://localhost:443"
|
||||||
|
admin_user = {"username": "rac00n", "password": "1248163264"}
|
||||||
|
|
||||||
|
def test_timezone_simple():
|
||||||
|
"""Simple test to verify timezone is Europe/Berlin"""
|
||||||
|
session = requests.Session()
|
||||||
|
|
||||||
|
print("Timezone Verification Test (Europe/Berlin)")
|
||||||
|
print("=" * 50)
|
||||||
|
|
||||||
|
# Test connection
|
||||||
|
try:
|
||||||
|
test_response = session.get(base_url, verify=True, timeout=5)
|
||||||
|
verify_ssl = True
|
||||||
|
print(f"✓ Using external URL: {base_url}")
|
||||||
|
except:
|
||||||
|
base_url_local = fallback_url
|
||||||
|
verify_ssl = False
|
||||||
|
print(f"ℹ Using fallback URL: {fallback_url}")
|
||||||
|
else:
|
||||||
|
base_url_local = base_url
|
||||||
|
|
||||||
|
# Show current times
|
||||||
|
utc_now = datetime.now(ZoneInfo("UTC"))
|
||||||
|
berlin_now = datetime.now(ZoneInfo("Europe/Berlin"))
|
||||||
|
|
||||||
|
print(f"\nCurrent times:")
|
||||||
|
print(f" UTC: {utc_now.strftime('%Y-%m-%d %H:%M:%S')}")
|
||||||
|
print(f" Berlin: {berlin_now.strftime('%Y-%m-%d %H:%M:%S')}")
|
||||||
|
|
||||||
|
# Calculate offset
|
||||||
|
time_diff = (berlin_now.hour - utc_now.hour) % 24
|
||||||
|
if berlin_now.day != utc_now.day:
|
||||||
|
# Handle day boundary
|
||||||
|
if berlin_now.day > utc_now.day:
|
||||||
|
time_diff = (berlin_now.hour + 24 - utc_now.hour) % 24
|
||||||
|
else:
|
||||||
|
time_diff = (berlin_now.hour - utc_now.hour - 24) % 24
|
||||||
|
|
||||||
|
print(f" Offset: +{time_diff} hours")
|
||||||
|
|
||||||
|
# Login
|
||||||
|
response = session.get(f"{base_url_local}/login", verify=verify_ssl)
|
||||||
|
if response.status_code != 200:
|
||||||
|
print(f"\n✗ Failed to access login page: {response.status_code}")
|
||||||
|
return
|
||||||
|
|
||||||
|
login_data = {
|
||||||
|
"username": admin_user["username"],
|
||||||
|
"password": admin_user["password"]
|
||||||
|
}
|
||||||
|
|
||||||
|
response = session.post(f"{base_url_local}/login", data=login_data, verify=verify_ssl, allow_redirects=False)
|
||||||
|
|
||||||
|
if response.status_code != 302:
|
||||||
|
print(f"\n✗ Login failed: {response.status_code}")
|
||||||
|
return
|
||||||
|
|
||||||
|
print(f"\n✓ Login successful")
|
||||||
|
|
||||||
|
# Check dashboard for any timestamps
|
||||||
|
print("\nChecking for timestamps in dashboard...")
|
||||||
|
response = session.get(f"{base_url_local}/", verify=verify_ssl)
|
||||||
|
if response.status_code == 200:
|
||||||
|
# Look for time patterns in dashboard
|
||||||
|
time_pattern = r'\d{2}:\d{2}:\d{2}'
|
||||||
|
times_found = re.findall(time_pattern, response.text)
|
||||||
|
if times_found:
|
||||||
|
print(f"✓ Found {len(times_found)} timestamps in dashboard")
|
||||||
|
# Check if any match current Berlin hour
|
||||||
|
berlin_hour = berlin_now.strftime("%H:")
|
||||||
|
if any(berlin_hour in time for time in times_found):
|
||||||
|
print(f"✓ Timestamps appear to use Berlin time (found {berlin_hour}xx)")
|
||||||
|
else:
|
||||||
|
print(f"ℹ Could not confirm timezone from timestamps")
|
||||||
|
else:
|
||||||
|
print("ℹ No timestamps found in dashboard")
|
||||||
|
|
||||||
|
# Check audit log
|
||||||
|
print("\nChecking audit log for LOGIN timestamp...")
|
||||||
|
response = session.get(f"{base_url_local}/audit", verify=verify_ssl)
|
||||||
|
if response.status_code == 200:
|
||||||
|
# Extract the most recent LOGIN entry
|
||||||
|
if "LOGIN_SUCCESS" in response.text:
|
||||||
|
# Look for timestamp near LOGIN_SUCCESS
|
||||||
|
berlin_time_str = berlin_now.strftime("%Y-%m-%d %H:")
|
||||||
|
if berlin_time_str in response.text:
|
||||||
|
print(f"✓ Audit log shows Berlin time (contains {berlin_time_str}xx)")
|
||||||
|
else:
|
||||||
|
utc_time_str = utc_now.strftime("%Y-%m-%d %H:")
|
||||||
|
if utc_time_str in response.text:
|
||||||
|
print(f"✗ Audit log might show UTC time (contains {utc_time_str}xx)")
|
||||||
|
else:
|
||||||
|
print(f"ℹ Could not determine timezone from audit log")
|
||||||
|
|
||||||
|
# Summary
|
||||||
|
print("\n" + "=" * 50)
|
||||||
|
print("Summary:")
|
||||||
|
if time_diff == 1:
|
||||||
|
print("✓ System timezone offset: +1 hour (CET - Winter time)")
|
||||||
|
elif time_diff == 2:
|
||||||
|
print("✓ System timezone offset: +2 hours (CEST - Summer time)")
|
||||||
|
else:
|
||||||
|
print(f"⚠ Unexpected timezone offset: +{time_diff} hours")
|
||||||
|
|
||||||
|
print("\nNote: The system should use Europe/Berlin timezone for all new data.")
|
||||||
|
print("Existing data created before the timezone change may still show UTC.")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
test_timezone_simple()
|
||||||
In neuem Issue referenzieren
Einen Benutzer sperren