Add some new fields for users table
This commit is contained in:
@@ -10,31 +10,39 @@ from db import get_conn
|
|||||||
# DB Initialisierung: `users`-Tabelle
|
# DB Initialisierung: `users`-Tabelle
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
def init_auth_db():
|
# def init_auth_db():
|
||||||
"""
|
# """
|
||||||
Legt die users-Tabelle an.
|
# Legt die users-Tabelle an.
|
||||||
WICHTIG: password_hash wird als TEXT gespeichert, damit sowohl
|
# WICHTIG: password_hash wird als TEXT gespeichert, damit sowohl
|
||||||
streamlit-authenticator als auch dein eigener bcrypt-Code kompatibel sind.
|
# streamlit-authenticator als auch dein eigener bcrypt-Code kompatibel sind.
|
||||||
"""
|
# """
|
||||||
with closing(get_conn()) as conn, conn:
|
# with closing(get_conn()) as conn, conn:
|
||||||
conn.execute(
|
# conn.execute(
|
||||||
"""
|
# """
|
||||||
CREATE TABLE IF NOT EXISTS users (
|
# CREATE TABLE IF NOT EXISTS users (
|
||||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
# id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
username TEXT UNIQUE NOT NULL,
|
# username TEXT UNIQUE NOT NULL,
|
||||||
email TEXT,
|
# email TEXT,
|
||||||
password_hash TEXT NOT NULL,
|
# password_hash TEXT NOT NULL,
|
||||||
role TEXT NOT NULL DEFAULT 'user'
|
# role TEXT NOT NULL DEFAULT 'user'
|
||||||
)
|
# )
|
||||||
"""
|
# """
|
||||||
)
|
# )
|
||||||
|
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
# Benutzer anlegen
|
# Benutzer anlegen
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
def create_user(username: str, password: str, role: str = "user", email: str | None = None) -> bool:
|
def create_user(
|
||||||
|
username: str,
|
||||||
|
password: str,
|
||||||
|
role: str = "user",
|
||||||
|
email: str | None = None,
|
||||||
|
firstname: str | None = None,
|
||||||
|
lastname: str | None = None
|
||||||
|
) -> bool:
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Passwort wird als bcrypt-Hash (TEXT) gespeichert.
|
Passwort wird als bcrypt-Hash (TEXT) gespeichert.
|
||||||
"""
|
"""
|
||||||
@@ -43,8 +51,8 @@ def create_user(username: str, password: str, role: str = "user", email: str | N
|
|||||||
try:
|
try:
|
||||||
with closing(get_conn()) as conn, conn:
|
with closing(get_conn()) as conn, conn:
|
||||||
conn.execute(
|
conn.execute(
|
||||||
"INSERT INTO users (username, email, password_hash, role) VALUES (?, ?, ?, ?)",
|
"INSERT INTO users (username, email, password_hash, role, firstname, lastname) VALUES (?, ?, ?, ?, ?, ?)",
|
||||||
(username, email, pw_hash, role),
|
(username, email, pw_hash, role, firstname, lastname),
|
||||||
)
|
)
|
||||||
return True
|
return True
|
||||||
except Exception:
|
except Exception:
|
||||||
|
|||||||
90
app/main.py
90
app/main.py
@@ -1,58 +1,94 @@
|
|||||||
# app/main.py
|
|
||||||
import streamlit as st
|
import streamlit as st
|
||||||
|
import yaml
|
||||||
from auth import (
|
from yaml.loader import SafeLoader
|
||||||
init_auth_db,
|
import streamlit_authenticator as stauth
|
||||||
ensure_logged_in,
|
from auth_core import load_credentials_from_db, get_role_for_user, create_user
|
||||||
authed_header,
|
from version import __version__
|
||||||
current_user,
|
|
||||||
create_user, # falls du Admin-Funktion brauchst
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def content_for(role: str, username: str):
|
def content_for(username: str, role: str):
|
||||||
st.header("Dashboard")
|
st.header("Controlling-Portal")
|
||||||
st.info(f"Willkommen, {username}!")
|
st.info(f"Willkommen, {username}!")
|
||||||
|
|
||||||
if role == "admin":
|
if role == "admin":
|
||||||
st.subheader("Admin-Bereich")
|
st.subheader("Admin-Bereich")
|
||||||
st.write("Nur Admins sehen das hier.")
|
st.write("Nur Admins sehen das hier.")
|
||||||
|
|
||||||
with st.expander("Neuen Nutzer anlegen"):
|
with st.expander("Neuen Nutzer anlegen"):
|
||||||
new_u = st.text_input("Neuer Username", key="new_u")
|
new_u = st.text_input("Neuer Username", key="new_u")
|
||||||
|
new_fname = st.text_input("Vorname", key="new_fname")
|
||||||
|
new_lname = st.text_input("Nachname", key="new_lname")
|
||||||
|
new_email = st.text_input("E-Mail", key="new_email")
|
||||||
new_p = st.text_input("Neues Passwort", type="password", key="new_p")
|
new_p = st.text_input("Neues Passwort", type="password", key="new_p")
|
||||||
new_role = st.selectbox("Rolle", ["user", "admin"], key="new_role")
|
new_role = st.selectbox("Rolle", ["user", "admin"], key="new_role")
|
||||||
|
|
||||||
if st.button("Anlegen"):
|
if st.button("Anlegen"):
|
||||||
if new_u and new_p:
|
if new_u and new_p:
|
||||||
ok = create_user(new_u.strip(), new_p, new_role)
|
ok = create_user(new_u.strip(), new_p, new_role, new_email, new_fname, new_lname)
|
||||||
st.success("Nutzer angelegt.") if ok else st.error(
|
st.success("Nutzer angelegt.") if ok else st.error("Username bereits vorhanden oder Fehler.")
|
||||||
"Username bereits vorhanden."
|
|
||||||
)
|
|
||||||
else:
|
else:
|
||||||
st.warning("Bitte Username und Passwort eingeben.")
|
st.warning("Bitte Username und Passwort eingeben.")
|
||||||
|
|
||||||
st.subheader("Dein Bereich")
|
st.subheader("Dein Bereich")
|
||||||
st.write(f"Personalisierter Content für **{username}**.")
|
st.write(f"Personalisierter Content für **{username}**.")
|
||||||
# fachliche Inhalte …
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
st.set_page_config(
|
st.set_page_config(
|
||||||
page_title="Intranet-Portal",
|
page_title=f"Co-App Start - V{__version__}",
|
||||||
page_icon="🔒",
|
page_icon="🔒",
|
||||||
layout="centered",
|
layout="centered",
|
||||||
)
|
)
|
||||||
|
|
||||||
init_auth_db()
|
# DB-Struktur sicherstellen
|
||||||
|
# init_auth_db()
|
||||||
|
|
||||||
# hier wird entweder:
|
# --- Config laden (Cookie, etc.) ---
|
||||||
# - st.session_state genutzt, oder
|
with open("config/auth.yaml", "r", encoding="utf-8") as f:
|
||||||
# - ?session_id=... aus URL geprüft, oder
|
base_config = yaml.load(f, Loader=SafeLoader)
|
||||||
# - Login-Form gezeigt (und Script gestoppt)
|
|
||||||
ensure_logged_in()
|
|
||||||
|
|
||||||
authed_header()
|
# --- Credentials dynamisch aus DB laden ---
|
||||||
username, role = current_user()
|
db_creds = load_credentials_from_db()
|
||||||
content_for(role, username)
|
base_config["credentials"] = db_creds
|
||||||
|
|
||||||
|
authenticator = stauth.Authenticate(
|
||||||
|
base_config["credentials"],
|
||||||
|
base_config["cookie"]["name"],
|
||||||
|
base_config["cookie"]["key"],
|
||||||
|
base_config["cookie"]["expiry_days"],
|
||||||
|
#base_config.get("preauthorized", {}),
|
||||||
|
)
|
||||||
|
|
||||||
|
#name, auth_status, username = authenticator.login(location="main", key="Login")
|
||||||
|
# login_result = authenticator.login(location="main", key="Login")
|
||||||
|
|
||||||
|
# if login_result is None:
|
||||||
|
# st.error("Login-Initialisierung fehlgeschlagen (keine gültigen Credentials?).")
|
||||||
|
# return
|
||||||
|
|
||||||
|
# name, auth_status, username = login_result
|
||||||
|
authenticator.login(location="main", key="Login")
|
||||||
|
|
||||||
|
auth_status = st.session_state.get("authentication_status")
|
||||||
|
name = st.session_state.get("name")
|
||||||
|
username = st.session_state.get("username")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if auth_status is False:
|
||||||
|
st.error("Login fehlgeschlagen.")
|
||||||
|
return
|
||||||
|
|
||||||
|
if auth_status is None:
|
||||||
|
st.warning("Bitte Benutzername und Passwort eingeben.")
|
||||||
|
return
|
||||||
|
|
||||||
|
# ---- Ab hier eingeloggt (persistenter Cookie) ----
|
||||||
|
role = get_role_for_user(username)
|
||||||
|
|
||||||
|
authenticator.logout("Logout", "sidebar")
|
||||||
|
st.sidebar.write(f"Angemeldet als **{name}** ({username}, Rolle: {role})")
|
||||||
|
|
||||||
|
content_for(username, role)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|||||||
59
app/main__.py
Normal file
59
app/main__.py
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
# app/main.py
|
||||||
|
import streamlit as st
|
||||||
|
|
||||||
|
from auth import (
|
||||||
|
init_auth_db,
|
||||||
|
ensure_logged_in,
|
||||||
|
authed_header,
|
||||||
|
current_user,
|
||||||
|
create_user, # falls du Admin-Funktion brauchst
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def content_for(role: str, username: str):
|
||||||
|
st.header("Dashboard")
|
||||||
|
st.info(f"Willkommen, {username}!")
|
||||||
|
|
||||||
|
if role == "admin":
|
||||||
|
st.subheader("Admin-Bereich")
|
||||||
|
st.write("Nur Admins sehen das hier.")
|
||||||
|
with st.expander("Neuen Nutzer anlegen"):
|
||||||
|
new_u = st.text_input("Neuer Username", key="new_u")
|
||||||
|
new_p = st.text_input("Neues Passwort", type="password", key="new_p")
|
||||||
|
new_role = st.selectbox("Rolle", ["user", "admin"], key="new_role")
|
||||||
|
if st.button("Anlegen"):
|
||||||
|
if new_u and new_p:
|
||||||
|
ok = create_user(new_u.strip(), new_p, new_role)
|
||||||
|
st.success("Nutzer angelegt.") if ok else st.error(
|
||||||
|
"Username bereits vorhanden."
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
st.warning("Bitte Username und Passwort eingeben.")
|
||||||
|
|
||||||
|
st.subheader("Dein Bereich")
|
||||||
|
st.write(f"Personalisierter Content für **{username}**.")
|
||||||
|
# fachliche Inhalte …
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
st.set_page_config(
|
||||||
|
page_title="Intranet-Portal",
|
||||||
|
page_icon="🔒",
|
||||||
|
layout="centered",
|
||||||
|
)
|
||||||
|
|
||||||
|
init_auth_db()
|
||||||
|
|
||||||
|
# hier wird entweder:
|
||||||
|
# - st.session_state genutzt, oder
|
||||||
|
# - ?session_id=... aus URL geprüft, oder
|
||||||
|
# - Login-Form gezeigt (und Script gestoppt)
|
||||||
|
ensure_logged_in()
|
||||||
|
|
||||||
|
authed_header()
|
||||||
|
username, role = current_user()
|
||||||
|
content_for(role, username)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
@@ -1,87 +0,0 @@
|
|||||||
# app/main.py
|
|
||||||
import streamlit as st
|
|
||||||
import yaml
|
|
||||||
from yaml.loader import SafeLoader
|
|
||||||
import streamlit_authenticator as stauth
|
|
||||||
|
|
||||||
from auth_core import (
|
|
||||||
init_auth_db,
|
|
||||||
load_credentials_from_db,
|
|
||||||
get_role_for_user,
|
|
||||||
create_user,
|
|
||||||
)
|
|
||||||
from version import __version__
|
|
||||||
|
|
||||||
|
|
||||||
def content_for(username: str, role: str):
|
|
||||||
st.header("Dashboard")
|
|
||||||
st.info(f"Willkommen, {username}!")
|
|
||||||
|
|
||||||
if role == "admin":
|
|
||||||
st.subheader("Admin-Bereich")
|
|
||||||
st.write("Nur Admins sehen das hier.")
|
|
||||||
|
|
||||||
with st.expander("Neuen Nutzer anlegen"):
|
|
||||||
new_u = st.text_input("Neuer Username", key="new_u")
|
|
||||||
new_email = st.text_input("E-Mail", key="new_email")
|
|
||||||
new_p = st.text_input("Neues Passwort", type="password", key="new_p")
|
|
||||||
new_role = st.selectbox("Rolle", ["user", "admin"], key="new_role")
|
|
||||||
|
|
||||||
if st.button("Anlegen"):
|
|
||||||
if new_u and new_p:
|
|
||||||
ok = create_user(new_u.strip(), new_p, new_role, new_email.strip() or None)
|
|
||||||
st.success("Nutzer angelegt.") if ok else st.error("Username bereits vorhanden oder Fehler.")
|
|
||||||
else:
|
|
||||||
st.warning("Bitte Username und Passwort eingeben.")
|
|
||||||
|
|
||||||
st.subheader("Dein Bereich")
|
|
||||||
st.write(f"Personalisierter Content für **{username}**.")
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
st.set_page_config(
|
|
||||||
page_title=f"Intranet-Portal v{__version__}",
|
|
||||||
page_icon="🔒",
|
|
||||||
layout="centered",
|
|
||||||
)
|
|
||||||
|
|
||||||
# DB-Struktur sicherstellen
|
|
||||||
init_auth_db()
|
|
||||||
|
|
||||||
# --- Config laden (Cookie, etc.) ---
|
|
||||||
with open("config/auth.yaml", "r", encoding="utf-8") as f:
|
|
||||||
base_config = yaml.load(f, Loader=SafeLoader)
|
|
||||||
|
|
||||||
# --- Credentials dynamisch aus DB laden ---
|
|
||||||
db_creds = load_credentials_from_db()
|
|
||||||
base_config["credentials"] = db_creds
|
|
||||||
|
|
||||||
authenticator = stauth.Authenticate(
|
|
||||||
base_config["credentials"],
|
|
||||||
base_config["cookie"]["name"],
|
|
||||||
base_config["cookie"]["key"],
|
|
||||||
base_config["cookie"]["expiry_days"],
|
|
||||||
base_config.get("preauthorized", {}),
|
|
||||||
)
|
|
||||||
|
|
||||||
name, auth_status, username = authenticator.login("Login", "main")
|
|
||||||
|
|
||||||
if auth_status is False:
|
|
||||||
st.error("Login fehlgeschlagen.")
|
|
||||||
return
|
|
||||||
|
|
||||||
if auth_status is None:
|
|
||||||
st.warning("Bitte Benutzername und Passwort eingeben.")
|
|
||||||
return
|
|
||||||
|
|
||||||
# ---- Ab hier eingeloggt (persistenter Cookie) ----
|
|
||||||
role = get_role_for_user(username)
|
|
||||||
|
|
||||||
authenticator.logout("Logout", "sidebar")
|
|
||||||
st.sidebar.write(f"Angemeldet als **{name}** ({username}, Rolle: {role})")
|
|
||||||
|
|
||||||
content_for(username, role)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
main()
|
|
||||||
@@ -6,7 +6,7 @@ from logging_config import setup_logging
|
|||||||
import os
|
import os
|
||||||
from contextlib import closing
|
from contextlib import closing
|
||||||
import getpass
|
import getpass
|
||||||
from auth import create_user
|
from auth_core import create_user
|
||||||
|
|
||||||
APP_ENV = os.environ.get("APP_ENV", "dev")
|
APP_ENV = os.environ.get("APP_ENV", "dev")
|
||||||
logger = setup_logging(APP_ENV)
|
logger = setup_logging(APP_ENV)
|
||||||
@@ -107,7 +107,14 @@ def create_admin_user():
|
|||||||
logger.warning("Passwörter stimmen nicht überein! Abbruch.")
|
logger.warning("Passwörter stimmen nicht überein! Abbruch.")
|
||||||
return
|
return
|
||||||
|
|
||||||
ok = create_user(ADMIN_USERNAME, pw1, role="admin")
|
ok = create_user(
|
||||||
|
username=ADMIN_USERNAME,
|
||||||
|
password=pw1,
|
||||||
|
role="admin",
|
||||||
|
email="admin@co_app",
|
||||||
|
firstname="co_app",
|
||||||
|
lastname="admin"
|
||||||
|
)
|
||||||
|
|
||||||
if ok:
|
if ok:
|
||||||
logger.info(f"Admin-Benutzer '{ADMIN_USERNAME}' wurde angelegt.")
|
logger.info(f"Admin-Benutzer '{ADMIN_USERNAME}' wurde angelegt.")
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
cookie:
|
cookie:
|
||||||
expiry_days: 7
|
expiry_days: 7
|
||||||
key: "please_change_this_cookie_signing_key"
|
key: "tHr1FXOYg-xsYBGVu7amRrY8PAdC2gM_zyjPEPPkPgG8tAsLY4QGPZvCvMS9win0D94uawAxsmZjN6O_VlRhUQ"
|
||||||
name: "intranet_session"
|
name: "co_app-session"
|
||||||
|
|
||||||
preauthorized:
|
preauthorized:
|
||||||
emails: []
|
emails: []
|
||||||
|
|||||||
BIN
data/app.db
BIN
data/app.db
Binary file not shown.
@@ -1,3 +1,5 @@
|
|||||||
|
begin;
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS sessions (
|
CREATE TABLE IF NOT EXISTS sessions (
|
||||||
id TEXT PRIMARY KEY,
|
id TEXT PRIMARY KEY,
|
||||||
username TEXT NOT NULL,
|
username TEXT NOT NULL,
|
||||||
@@ -5,6 +7,7 @@ CREATE TABLE IF NOT EXISTS sessions (
|
|||||||
expires_at INTEGER NOT NULL,
|
expires_at INTEGER NOT NULL,
|
||||||
FOREIGN KEY (username) REFERENCES users(username) ON DELETE CASCADE
|
FOREIGN KEY (username) REFERENCES users(username) ON DELETE CASCADE
|
||||||
);
|
);
|
||||||
|
|
||||||
INSERT INTO schema_version (version) VALUES ('20251129_162900_add_table_sessions');
|
INSERT INTO schema_version (version) VALUES ('20251129_162900_add_table_sessions');
|
||||||
|
|
||||||
COMMIT;
|
COMMIT;
|
||||||
8
migrations/20251130_124700_add_col_email_users.sql
Normal file
8
migrations/20251130_124700_add_col_email_users.sql
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
begin;
|
||||||
|
|
||||||
|
alter table users
|
||||||
|
add column email text not null;
|
||||||
|
|
||||||
|
INSERT INTO schema_version (version) VALUES ('20251130_124700_add_col_email_users');
|
||||||
|
|
||||||
|
COMMIT;
|
||||||
11
migrations/20251130_1411_add_col_name_users.sql
Normal file
11
migrations/20251130_1411_add_col_name_users.sql
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
begin;
|
||||||
|
|
||||||
|
alter table users
|
||||||
|
add column firstname text;
|
||||||
|
|
||||||
|
alter table users
|
||||||
|
add column lastname text;
|
||||||
|
|
||||||
|
INSERT INTO schema_version (version) VALUES ('20251130_1411_add_col_name_users');
|
||||||
|
|
||||||
|
COMMIT;
|
||||||
Reference in New Issue
Block a user