Skip to content

Commit

Permalink
Some minor bug fixes still a long way to go
Browse files Browse the repository at this point in the history
  • Loading branch information
lifeisacanvas24 committed Oct 12, 2024
1 parent cc94bdd commit 7c063ee
Show file tree
Hide file tree
Showing 2,862 changed files with 676,806 additions and 89 deletions.
Binary file added zola-admin/admin_app.db
Binary file not shown.
Binary file modified zola-admin/app/__pycache__/auth.cpython-312.pyc
Binary file not shown.
Binary file modified zola-admin/app/__pycache__/crud.cpython-312.pyc
Binary file not shown.
Binary file modified zola-admin/app/__pycache__/main.cpython-312.pyc
Binary file not shown.
48 changes: 31 additions & 17 deletions zola-admin/app/auth.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
#app/auth.py
from fastapi import APIRouter, Depends, HTTPException, status, Response, Cookie
from sqlalchemy.orm import Session
from app.crud import get_user, verify_password
Expand All @@ -10,33 +9,48 @@

pwd_context = CryptContext(schemes=["pbkdf2_sha256"], deprecated="auto")

# Improved: Authenticate User
def authenticate_user(username: str, password: str, db: Session):
user = get_user(db, username=username)
if user and verify_password(password, user.hashed_password):
return user
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Invalid credentials",
headers={"WWW-Authenticate": "Bearer"}
)
if user is None:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="User not found",
headers={"WWW-Authenticate": "Bearer"}
)

if not verify_password(password, user.hashed_password):
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Incorrect password",
headers={"WWW-Authenticate": "Bearer"}
)

return user

# Improved: Fetch user ID from cookie and handle errors
def get_user_id_from_cookie(user_id: str = Cookie(None)):
if user_id is None:
raise HTTPException(status_code=403, detail="Not authenticated")
if not user_id or not user_id.isdigit():
raise HTTPException(status_code=403, detail="Invalid or missing authentication cookie")
return int(user_id)

# User login handler
@router.post("/login")
async def login(response: Response, username: str, password: str, db: Session = Depends(get_db)):
user = authenticate_user(username, password, db)
if not user:
raise HTTPException(status_code=400, detail="Invalid credentials")

response.set_cookie(key="user_id", value=str(user.id), httponly=True)
response.set_cookie(key="user_id", value=str(user.id), httponly=True, secure=True, samesite="Lax")
return {"detail": "Login successful"}

def get_current_user(db: Session = Depends(get_db), user_id: int = Depends(get_user_id_from_cookie)):
# Get current user by session
async def get_current_user(db: Session = Depends(get_db)):
user_id = get_user_id_from_cookie() # Your cookie retrieval logic
logging.info(f"Attempting to retrieve user ID: {user_id}")
if user_id is None:
logging.warning("User ID is None. User is not authenticated.")
return None
user = db.query(User).filter(User.id == user_id).first()
if user is None:
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid authentication credentials")

logging.warning("No user found for the provided ID.")
return None
logging.info(f"Authenticated user: {user.username}")
return user
1 change: 1 addition & 0 deletions zola-admin/app/crud.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@

from sqlalchemy.orm import Session
from app.models import User
from app.schemas import UserCreate, UserUpdate
Expand Down
98 changes: 70 additions & 28 deletions zola-admin/app/main.py
Original file line number Diff line number Diff line change
@@ -1,75 +1,117 @@
#app/main.py
from fastapi import FastAPI, Depends, Request, Form, HTTPException
from fastapi.responses import RedirectResponse, HTMLResponse
from fastapi.templating import Jinja2Templates
from sqlalchemy.orm import Session
from app.auth import authenticate_user, get_current_user
from app.auth import authenticate_user, get_current_user, get_user_id_from_cookie
from app.crud import create_user
from app.init_db import init_db
import logging
from app.dependencies import get_db
from app.routers import user as user_router
from app.routers import admin as admin_router
from app.database import Base, engine
from app.dependencies import get_db
from fastapi.staticfiles import StaticFiles
from contextlib import asynccontextmanager
from starlette.middleware.base import BaseHTTPMiddleware
import logging

logging.basicConfig(level=logging.INFO)
logging.getLogger('sqlalchemy.engine').setLevel(logging.INFO)

app = FastAPI()
# Example async context manager for lifespan
@asynccontextmanager
async def lifespan(app: FastAPI):
init_db() # Initialize the database connection or other startup tasks
yield # This is where the app runs
# Cleanup can be done here if necessary

# Async context manager for database session
@asynccontextmanager
async def get_db_session():
db = next(get_db())
try:
yield db
finally:
db.close()

app = FastAPI(lifespan=lifespan)

app.include_router(admin_router.router, prefix="/admin", tags=["admin"])
app.include_router(user_router.router, prefix="/admin", tags=["users"])

@app.middleware("http")
async def add_user_to_request(request: Request, call_next):
try:
request.state.user = await get_current_user(request)
except HTTPException:
request.state.user = None
# Middleware to add user information to the request
class AddUserMiddleware(BaseHTTPMiddleware):
async def dispatch(self, request: Request, call_next):
async with get_db_session() as db:
try:
user_id = get_user_id_from_cookie(request.cookies.get("user_id"))
if user_id:
request.state.user = await get_current_user(db=db, user_id=user_id)
logging.info(f"User ID retrieved from cookie: {user_id}")
if request.state.user:
logging.info(f"User retrieved: {request.state.user.username}")
else:
request.state.user = None
except HTTPException as e:
logging.error(f"HTTPException in middleware: {e.detail}")
request.state.user = None
except Exception as e:
logging.error(f"Error in middleware: {e}")
request.state.user = None

response = await call_next(request)
return response
response = await call_next(request)
return response

# Add middleware to the app
app.add_middleware(AddUserMiddleware)

app.mount("/static", StaticFiles(directory="app/static"), name="static")

templates = Jinja2Templates(directory="app/templates")

@app.on_event("startup")
def on_startup():
init_db()

Base.metadata.create_all(bind=engine)

@app.get("/")
async def read_root():
return {"message": "Welcome to the Admin Dashboard"}

@app.get("/admin/")
def login_page(request: Request):
async def login_page(request: Request):
return templates.TemplateResponse("login.html", {"request": request, "user": request.state.user})

@app.post("/login/")
def login(request: Request, username: str = Form(...), password: str = Form(...), db: Session = Depends(get_db)):
async def login(request: Request, username: str = Form(...), password: str = Form(...), db: Session = Depends(get_db)):
user = authenticate_user(username, password, db)
if not user:
raise HTTPException(status_code=400, detail="Invalid credentials")
logging.warning(f"Failed login attempt for user: {username}")
return templates.TemplateResponse("login.html", {
"request": request, "error": "Invalid credentials, please try again."
})

# Set the user in cookie and redirect to the dashboard
response = RedirectResponse(url="/dashboard/", status_code=302)
response.set_cookie(key="username", value=user.username)
response.set_cookie(key="user_id", value=str(user.id), httponly=True, secure=False, samesite="Lax")
return response

@app.get("/dashboard/")
def dashboard(request: Request):
async def dashboard(request: Request):
if not request.state.user:
return RedirectResponse(url="/admin/")
return templates.TemplateResponse("dashboard.html", {"request": request})

# Log current user info
logging.info(f"Current user: {request.state.user.username}")

return templates.TemplateResponse("dashboard.html", {
"request": request,
"user": request.state.user # Pass user context
})

@app.get("/logout/")
def logout():
async def logout():
response = RedirectResponse(url="/logout-confirmation/")
response.delete_cookie("username")
response.delete_cookie("user_id") # Remove the user_id cookie
return response

@app.get("/logout-confirmation/", response_class=HTMLResponse)
async def logout_confirmation(request: Request):
return templates.TemplateResponse("logout_confirmation.html", {"request": request})
return templates.TemplateResponse("logout_confirmation.html", {
"request": request,
"user": request.state.user # Pass the user object to the template
})
Binary file modified zola-admin/app/routers/__pycache__/admin.cpython-312.pyc
Binary file not shown.
18 changes: 12 additions & 6 deletions zola-admin/app/routers/admin.py
Original file line number Diff line number Diff line change
@@ -1,26 +1,31 @@
#app/routers/admin.py
from fastapi import APIRouter, Depends, Request, HTTPException, Form
# app/routers/admin.py
from fastapi import APIRouter, Depends, Request, Form
from fastapi.responses import RedirectResponse, HTMLResponse
from app.auth import get_current_user
from app.models import User
from app.database import get_db
from app import schemas, crud
from sqlalchemy.orm import Session
from starlette.templating import Jinja2Templates
import logging

router = APIRouter()
templates = Jinja2Templates(directory="app/templates") # Ensure this path is correct

# User Creation Page - GET
@router.get("/users/create-user/", response_class=HTMLResponse)
def create_user_page(request: Request, current_user: User = Depends(get_current_user)):
if not current_user.is_authenticated:
async def create_user_page(request: Request, current_user: User = Depends(get_current_user)):
logging.info(f"User accessing create user page: {current_user.username if current_user else 'Guest'}")

if current_user is None: # You might prefer to check for `None` explicitly.
logging.warning("Unauthorized access attempt to create user page.")
return RedirectResponse(url="/admin/")

return templates.TemplateResponse("create_user.html", {"request": request, "title": "Create User"})

# Create New User - POST
@router.post("/users/create-user-post/")
def create_new_user(
async def create_new_user(
request: Request,
username: str = Form(...),
password: str = Form(...),
Expand All @@ -33,6 +38,7 @@ def create_new_user(
try:
db_user = crud.create_user(db, user=new_user_data)
# After creating the user, redirect to a success page
return templates.TemplateResponse("create_user_success.html", {"request": request, "username": username})
return RedirectResponse(url="/admin/users/list", status_code=303) # Assuming you have a list page
except Exception as e:
logging.error(f"Error creating user: {str(e)}")
return templates.TemplateResponse("create_user.html", {"request": request, "error": str(e)})
30 changes: 3 additions & 27 deletions zola-admin/app/templates/base.html
Original file line number Diff line number Diff line change
Expand Up @@ -10,29 +10,11 @@
<link rel="stylesheet" href="{{ url_for('static', path='css/style.css') }}">
</head>
<body>
<nav class="navbar">
<div class="navbar-brand">
<a class="navbar-item" href="/">Admin Dashboard</a>
<div class="navbar-burger" id="navbar-burger">
<span></span>
<span></span>
<span></span>
</div>
</div>
<div id="navbar-menu" class="navbar-menu">
<div class="navbar-end">
{% if user.is_authenticated %}
<a class="navbar-item" href="/logout/">Logout</a>
{% else %}
<a class="navbar-item" href="/admin/">Login</a>
{% endif %}
</div>
</div>
</nav>
{% include 'header.html' %} <!-- Include the header -->

<div class="columns">
<div class="column is-3">
{% if user.is_authenticated %}
{% if user %}
{% include 'sidebar.html' %}
{% endif %}
</div>
Expand All @@ -42,13 +24,7 @@
</div>
</div>

<footer class="footer">
<div class="content has-text-centered">
<p>
<strong>Admin Dashboard</strong> by Your Name.
</p>
</div>
</footer>
{% include 'footer.html' %} <!-- Include the footer -->

<script>
document.addEventListener('DOMContentLoaded', () => {
Expand Down
16 changes: 11 additions & 5 deletions zola-admin/app/templates/dashboard.html
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
{% extends "base.html" %}

{% block content %}
<div class="container">
<h1 class="title">Welcome, {{ username }}</h1>
<p class="subtitle">You are now logged in.</p>
<a href="/logout" class="button is-danger">Logout</a>

</div>
{% if user %}
<div class="container">
<h1 class="title">Welcome, {{ user.username }}</h1> <!-- Access username through user object -->
<p class="subtitle">You are now logged in.</p>
<a href="/logout" class="button is-danger">Logout</a>
</div>
{% else %}
<div class="container">
<p>You have not managed to log in. Please click here to <a href="/admin/" class="button is-danger">Login</a>.</p>
</div>
{% endif %}

{% endblock %}
9 changes: 6 additions & 3 deletions zola-admin/app/templates/header.html
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@

<!-- templates/header.html -->
<nav class="navbar is-dark" role="navigation" aria-label="main navigation">
<div class="navbar-brand">
Expand All @@ -7,9 +8,11 @@
</div>
<div id="navbarBasicExample" class="navbar-menu">
<div class="navbar-end">
<a class="navbar-item">
Logout
</a>
{% if user %}
<a class="navbar-item" href="/logout/">Logout</a>
{% else %}
<a class="navbar-item" href="/admin/">Login</a>
{% endif %}
</div>
</div>
</nav>
12 changes: 10 additions & 2 deletions zola-admin/app/templates/logout_confirmation.html
Original file line number Diff line number Diff line change
@@ -1,8 +1,16 @@
{% extends "base.html" %}

{% block content %}

<div class="container">
<h1 class="title">You have been logged out</h1>
<p>Thank you for visiting. Click <a href="/admin/">here</a> to log in again.</p>
<h1 class="title">Logout Confirmation</h1>

{% if user %}
<p>Goodbye, {{ user.username }}! You have successfully logged out.</p>
<a href="/admin/" class="button">Login Again</a>
{% else %}
<p>You are not logged in. Please click here to <a href="/admin/" class="button">Login</a>.</p>
{% endif %}
</div>

{% endblock %}
2 changes: 1 addition & 1 deletion zola-admin/app/templates/sidebar.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<!-- templates/sidebar.html -->
{% if user.is_authenticated %}
{% if user %}
<aside class="menu">
<p class="menu-label">Manage Users</p>
<ul class="menu-list">
Expand Down
Loading

0 comments on commit 7c063ee

Please sign in to comment.