Add pages permission
This commit is contained in:
Binary file not shown.
@@ -15,3 +15,4 @@ def get_list(sql, params=None):
|
||||
df = pd.read_sql_query(sql, conn, params=params)
|
||||
conn.close()
|
||||
return df
|
||||
|
||||
|
||||
58
app/auth.py
58
app/auth.py
@@ -2,7 +2,7 @@
|
||||
from contextlib import closing
|
||||
import bcrypt
|
||||
|
||||
from app_db.app_db import get_conn
|
||||
from app_db.app_db import get_conn, get_list
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
@@ -35,7 +35,7 @@ def create_user(
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Benutzer überprüfen (z.B. für deine alte Streamlit-Login-Maske)
|
||||
# Benutzer überprüfen
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
def verify_user(username: str, password: str):
|
||||
@@ -84,6 +84,60 @@ def get_fullname_for_user(username: str) -> str:
|
||||
).fetchone()
|
||||
return row[0] if row else "user"
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Sidebar-Einträge für den Benutzer
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
def get_sidebar(role_text: str, username: str):
|
||||
if role_text == "admin":
|
||||
sql = """
|
||||
select
|
||||
g.group_id,
|
||||
g.group_text,
|
||||
d.dash_id,
|
||||
d.dash_text,
|
||||
d.page_file,
|
||||
d.dash_type
|
||||
from
|
||||
groups g
|
||||
left join dashboards d
|
||||
on g.group_id = d.group_id
|
||||
where
|
||||
g.active = 1
|
||||
and d.active = 1
|
||||
"""
|
||||
else:
|
||||
sql = """
|
||||
SELECT
|
||||
d.group_id,
|
||||
g.group_text,
|
||||
p.dash_id,
|
||||
d.dash_text,
|
||||
d.page_file,
|
||||
d.dash_type
|
||||
FROM
|
||||
users u
|
||||
left join permissions p
|
||||
on u.role_id = p.role_id
|
||||
left join dashboards d
|
||||
on p.dash_id = d.dash_id
|
||||
left join groups g
|
||||
on d.group_id = g.group_id
|
||||
where
|
||||
u.active = 1
|
||||
and g.active = 1
|
||||
and d.active = 1
|
||||
and p.active = 1
|
||||
and u.username = ?
|
||||
order by
|
||||
g.order_no,
|
||||
d.order_no
|
||||
"""
|
||||
params = (username,) if "?" in sql else None
|
||||
df = get_list(sql, params)
|
||||
|
||||
return df
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Credential-Lader für streamlit-authenticator
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
@@ -10,7 +10,7 @@ def get_authenticator():
|
||||
with open("config/auth.yaml", "r", encoding="utf-8") as f:
|
||||
base_config = yaml.load(f, Loader=SafeLoader)
|
||||
|
||||
db_creds = load_credentials_from_db()
|
||||
db_creds = load_credentials_from_db() # Hier wird name, email und password geladen
|
||||
base_config["credentials"] = db_creds
|
||||
|
||||
authenticator = stauth.Authenticate(
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
|
||||
import streamlit as st
|
||||
from auth_runtime import require_login
|
||||
from ui.sidebar import build_sidebar, hide_sidebar_if_logged_out
|
||||
from auth import get_fullname_for_user
|
||||
|
||||
hide_sidebar_if_logged_out()
|
||||
|
||||
st.set_page_config(page_title="Co-App Home", page_icon="🏠")
|
||||
|
||||
authenticator = require_login()
|
||||
st.session_state["authenticator"] = authenticator
|
||||
|
||||
build_sidebar()
|
||||
|
||||
def render(username: str, role: str):
|
||||
st.title("Benutzerverwaltung")
|
||||
|
||||
with st.expander("Neuen Nutzer anlegen"):
|
||||
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_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,
|
||||
new_fname.strip() or None,
|
||||
new_lname.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}**.")
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
import importlib
|
||||
|
||||
def get_dashboard_renderer(code: str):
|
||||
"""
|
||||
Liefert die passende Render-Funktion zum Dashboard-Code.
|
||||
- "home" -> interne Funktion home_dashboard
|
||||
- alles andere -> Modul app.dashboards.<code> mit Funktion render(username, role)
|
||||
"""
|
||||
if code == "home":
|
||||
return home_dashboard
|
||||
|
||||
module_name = f"app.dashboards.{code}"
|
||||
try:
|
||||
module = importlib.import_module(module_name)
|
||||
except ModuleNotFoundError:
|
||||
# Zum Debuggen:
|
||||
st.error(f"Modul '{module_name}' wurde nicht gefunden.")
|
||||
return None
|
||||
|
||||
if not hasattr(module, "render"):
|
||||
st.error(f"Modul '{module_name}' hat keine Funktion render().")
|
||||
return None
|
||||
|
||||
return module.render
|
||||
@@ -1,46 +0,0 @@
|
||||
import streamlit as st
|
||||
from auth import create_user, get_fullname_for_user, get_role_for_user
|
||||
from ui.sidebar import build_sidebar
|
||||
|
||||
build_sidebar
|
||||
|
||||
st.header("Controlling-Portal")
|
||||
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_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_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,
|
||||
# new_fname.strip() or None,
|
||||
# new_lname.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}**.")
|
||||
29
app/main.py
29
app/main.py
@@ -2,31 +2,54 @@ import streamlit as st
|
||||
import logging
|
||||
from logging_config import setup_logging
|
||||
from version import __version__
|
||||
from auth import get_role_for_user, get_fullname_for_user, get_sidebar
|
||||
from auth_runtime import require_login
|
||||
from ui.sidebar import build_sidebar
|
||||
import os
|
||||
from app_db.app_db import get_list
|
||||
|
||||
APP_ENV = os.environ.get("APP_ENV", "dev")
|
||||
|
||||
logger = setup_logging(APP_ENV)
|
||||
#logger.info(f"Starting migration - APP-Version {__version__}")
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
def main():
|
||||
st.set_page_config(
|
||||
page_title=f"Co-App Start - V{__version__}",
|
||||
page_title=f"Co-App Home - V{__version__}",
|
||||
page_icon="🔒",
|
||||
layout="centered",
|
||||
)
|
||||
|
||||
authenticator = require_login()
|
||||
# damit build_sidebar den authenticator findet:
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
# Ab hier ist Benutzer angemeldet!!
|
||||
#--------------------------------------------------------------------------------
|
||||
|
||||
# Alles was man so braucht in der App wird in session_state abgelegt
|
||||
|
||||
# zuerst den authenticator holen ...
|
||||
st.session_state["authenticator"] = authenticator
|
||||
# ... dann ist der name des users in der sesstion_state verfügbar!
|
||||
|
||||
|
||||
# Ich suche mir erst mal alles zusammen, was ich dann in session_state speichern will ...
|
||||
username = st.session_state.get("name") # wird duch authenticator gesetzt
|
||||
role_text = get_role_for_user(username)
|
||||
fullname = get_fullname_for_user(username)
|
||||
sidebar = get_sidebar(role_text, username)
|
||||
|
||||
# ... und lege es dann im session_state ab.
|
||||
st.session_state["role_text"] = role_text
|
||||
st.session_state["fullname"] = fullname
|
||||
st.session_state["df_sidebar"] = sidebar
|
||||
|
||||
build_sidebar()
|
||||
|
||||
st.header("Controlling-Portal")
|
||||
st.info(f"Willkommen, {st.session_state.get('username')}!")
|
||||
|
||||
st.text("Hier könnte eine Nachricht für den Benutzer stehen")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -2,6 +2,16 @@ import streamlit as st
|
||||
import pandas as pd
|
||||
from data.scriptloader import get_sql
|
||||
from data.db import get_conn
|
||||
from auth_runtime import require_login
|
||||
from ui.sidebar import build_sidebar, hide_sidebar_if_logged_out
|
||||
from auth import get_fullname_for_user
|
||||
|
||||
hide_sidebar_if_logged_out()
|
||||
|
||||
st.set_page_config(page_title="Co-App Home", page_icon="🏠")
|
||||
|
||||
authenticator = require_login()
|
||||
st.session_state["authenticator"] = authenticator
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -10,8 +10,9 @@ st.set_page_config(page_title="Co-App Home", page_icon="🏠")
|
||||
authenticator = require_login()
|
||||
st.session_state["authenticator"] = authenticator
|
||||
|
||||
build_sidebar()
|
||||
#build_sidebar()
|
||||
|
||||
username = st.session_state.get("username")
|
||||
st.header("Controlling-Portal")
|
||||
st.info(f"Willkommen, {get_fullname_for_user(username)}!")
|
||||
st.markdown("**Hier könnte eine Hinweistext für den Benutzer stehen**")
|
||||
@@ -2,16 +2,25 @@ import streamlit as st
|
||||
from auth_runtime import require_login
|
||||
from ui.sidebar import hide_sidebar_if_logged_out
|
||||
from auth import create_user
|
||||
from pathlib import Path
|
||||
from tools.check_permission import check
|
||||
|
||||
DASH_NAME = Path(__file__).stem # Hier muss die dash_id aus der DB stehen -> wird gegen die session_state geprüft (User-Berechtigung)
|
||||
|
||||
|
||||
|
||||
hide_sidebar_if_logged_out()
|
||||
|
||||
st.set_page_config(page_title="Co-App Home", page_icon="🏠")
|
||||
st.set_page_config(page_title="Co-App Benutzer", page_icon="🏠")
|
||||
|
||||
authenticator = require_login()
|
||||
st.session_state["authenticator"] = authenticator
|
||||
username = st.session_state.get("username")
|
||||
df = st.session_state.get("df_sidebar")
|
||||
|
||||
# build_sidebar()
|
||||
if check(df,DASH_NAME) == False:
|
||||
st.markdown("**FEHLER**")
|
||||
st.error("Die Seite kann nicht angezeigt werden - keine Berechtigung!")
|
||||
st.stop()
|
||||
|
||||
st.title("Benutzerverwaltung")
|
||||
|
||||
|
||||
27
app/tools/check_permission.py
Normal file
27
app/tools/check_permission.py
Normal file
@@ -0,0 +1,27 @@
|
||||
import streamlit as st
|
||||
from auth_runtime import require_login
|
||||
from auth import get_sidebar, get_fullname_for_user, get_role_for_user
|
||||
|
||||
|
||||
|
||||
def check(df, page_name):
|
||||
if "df_sidebar" not in st.session_state:
|
||||
# authenticator = require_login()
|
||||
username = st.session_state.get("username")
|
||||
role_text = get_role_for_user(username)
|
||||
fullname = get_fullname_for_user(username)
|
||||
df = get_sidebar(role_text, username)
|
||||
|
||||
st.session_state["role_text"] = role_text
|
||||
st.session_state["fullname"] = fullname
|
||||
st.session_state["df_sidebar"] = df
|
||||
|
||||
if df is None or df.empty:
|
||||
return False # oder True – je nach gewünschtem Verhalten
|
||||
|
||||
allowed = not df[
|
||||
(df["dash_type"] == "page") &
|
||||
(df["page_file"] == page_name)
|
||||
].empty
|
||||
|
||||
return True
|
||||
@@ -11,64 +11,18 @@ def build_sidebar():
|
||||
return
|
||||
|
||||
authenticator = st.session_state.get("authenticator")
|
||||
username = st.session_state.get("username")
|
||||
username = st.session_state.get("name")
|
||||
role_text = st.session_state.get("role_text")
|
||||
fullname = st.session_state.get("fullname")
|
||||
|
||||
if not authenticator or not username:
|
||||
return
|
||||
|
||||
role = get_role_for_user(username)
|
||||
fullname = get_fullname_for_user(username)
|
||||
|
||||
if role == "admin":
|
||||
sql = """
|
||||
select
|
||||
g.group_id,
|
||||
g.group_text,
|
||||
d.dash_id,
|
||||
d.dash_text,
|
||||
d.page_file,
|
||||
d.dash_type
|
||||
from
|
||||
groups g
|
||||
left join dashboards d
|
||||
on g.group_id = d.group_id
|
||||
where
|
||||
g.active = 1
|
||||
and d.active = 1
|
||||
"""
|
||||
else:
|
||||
sql = """
|
||||
SELECT
|
||||
d.group_id,
|
||||
g.group_text,
|
||||
p.dash_id,
|
||||
d.dash_text,
|
||||
d.page_file,
|
||||
d.dash_type
|
||||
FROM
|
||||
users u
|
||||
left join permissions p
|
||||
on u.role_id = p.role_id
|
||||
left join dashboards d
|
||||
on p.dash_id = d.dash_id
|
||||
left join groups g
|
||||
on d.group_id = g.group_id
|
||||
where
|
||||
u.active = 1
|
||||
and g.active = 1
|
||||
and d.active = 1
|
||||
and p.active = 1
|
||||
and u.username = ?
|
||||
order by
|
||||
g.order_no,
|
||||
d.order_no
|
||||
"""
|
||||
params = (username,) if "?" in sql else None
|
||||
df = get_list(sql, params)
|
||||
df = st.session_state.get("df_sidebar")
|
||||
|
||||
with st.sidebar:
|
||||
st.logo("app/images/GMN_Logo_neu_rgb.png", size="small")
|
||||
st.write(f"**{fullname}** ({role})")
|
||||
st.markdown(f"**{fullname}** ({role_text})")
|
||||
|
||||
col1, col2 = st.columns(2)
|
||||
with col1:
|
||||
@@ -81,32 +35,6 @@ def build_sidebar():
|
||||
st.divider()
|
||||
st.markdown("## Menü")
|
||||
|
||||
# for group_text, df_group in df.groupby("group_text"):
|
||||
# with st.expander(group_text, expanded=False):
|
||||
# for _, row in df_group.iterrows():
|
||||
# dash_type = row.get("dash_type")
|
||||
# page_file = row.get("page_file")
|
||||
# label = row.get("dash_text", "")
|
||||
# print(dash_type, page_file, label)
|
||||
# # 1) echte Streamlit-Page
|
||||
# if dash_type == "page" and isinstance(page_file, str) and page_file.strip():
|
||||
# st.page_link(
|
||||
# page_file, # z.B. "pages/umsatz.py"
|
||||
# label=label,
|
||||
# )
|
||||
|
||||
# # 2) externer Link (oder interner HTTP-Link)
|
||||
# elif dash_type == "url" and isinstance(page_file, str) and page_file.strip():
|
||||
# st.markdown(
|
||||
# f"[{label}]({page_file})",
|
||||
# unsafe_allow_html=False,
|
||||
# )
|
||||
|
||||
# # 3) Platzhalter / noch nicht implementiert
|
||||
# else:
|
||||
# st.write(f"▫️ {label} (in Vorbereitung)")
|
||||
|
||||
|
||||
# --- Suchfeld ---
|
||||
query = st.text_input("Menü-Suche", "", placeholder="z.B. Umsatz, Kosten, User ...")
|
||||
query = query.strip()
|
||||
@@ -145,7 +73,7 @@ def build_sidebar():
|
||||
|
||||
# Streamlit-Page
|
||||
if dash_type == "page" and isinstance(page_file, str) and page_file.strip():
|
||||
st.page_link(page_file, label=label)
|
||||
st.page_link(f"pages/{page_file}.py", label=label)
|
||||
|
||||
# Externer Link
|
||||
elif dash_type == "url" and isinstance(page_file, str) and page_file.strip():
|
||||
|
||||
Reference in New Issue
Block a user