[PR #117] [MERGED] Added optional authentication and user management #931

Closed
opened 2026-05-06 12:34:01 +02:00 by BreizhHardware · 0 comments

📋 Pull Request Information

Original PR: https://github.com/maziggy/bambuddy/pull/117
Author: @JesseFPV
Created: 1/21/2026
Status: Merged
Merged: 1/21/2026
Merged by: @maziggy

Base: mainHead: main


📝 Commits (5)

  • f8857ba Added optional authentication and user management
  • 3e1843f Updated checks
  • d731cd2 Fixed lint errors
  • deeaabf Fixed frontend lint test error
  • 6e5cc55 Fixed auth check and conftest

📊 Changes

30 files changed (+10808 additions, -8775 deletions)

View changed files

backend/app/api/routes/auth.py (+213 -0)
📝 backend/app/api/routes/printers.py (+4 -0)
backend/app/api/routes/users.py (+205 -0)
📝 backend/app/core/auth.py (+306 -61)
📝 backend/app/core/database.py (+20 -0)
📝 backend/app/main.py (+4 -0)
📝 backend/app/models/__init__.py (+2 -0)
backend/app/models/user.py (+20 -0)
backend/app/schemas/auth.py (+47 -0)
📝 backend/tests/conftest.py (+1 -0)
📝 frontend/package-lock.json (+39 -14)
📝 frontend/package.json (+1 -0)
📝 frontend/src/App.tsx (+89 -23)
📝 frontend/src/__tests__/components/Layout.test.tsx (+3 -0)
📝 frontend/src/__tests__/pages/SettingsPage.test.tsx (+3 -0)
📝 frontend/src/__tests__/utils.tsx (+4 -1)
📝 frontend/src/api/client.ts (+121 -4)
📝 frontend/src/components/Layout.tsx (+33 -1)
frontend/src/contexts/AuthContext.tsx (+116 -0)
frontend/src/pages/LoginPage.tsx (+103 -0)

...and 10 more files

📄 Description

Description

This PR adds a comprehensive authentication and authorization system to Bambuddy, allowing administrators to secure their instance with user authentication and role-based access control. The system is fully optional and maintains backward compatibility - existing installations without authentication will continue to work as before.

Fixes #

Type of Change

  • New feature (non-breaking change that adds functionality)
  • Bug fix (non-breaking change that fixes an issue)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update
  • Code refactoring
  • Performance improvement
  • Test addition or update

Changes Made

Backend Changes

  • User Model & Database Migration

    • Added User model with username, password hash, role, and active status
    • Database migration creates users table with proper indexes
    • Supports two roles: admin and user
  • Authentication Core (backend/app/core/auth.py)

    • Password hashing using pbkdf2_sha256 (secure alternative to bcrypt without 72-byte limit)
    • JWT token generation and validation
    • FastAPI dependencies for authentication and authorization:
      • get_current_user - Requires valid JWT token
      • get_current_active_user - Requires active user account
      • require_auth_if_enabled - Optional auth when enabled
      • require_role(role) - Role-based access control
      • RequireAdmin() - Admin-only dependency
      • RequireAdminIfAuthEnabled() - Admin-only when auth is enabled
    • API key authentication helpers (get_api_key, check_permission, check_printer_access)
  • Authentication Routes (backend/app/api/routes/auth.py)

    • POST /auth/setup - First-time setup to enable/disable authentication and create admin user
    • GET /auth/status - Public endpoint to check authentication status
    • POST /auth/login - User login endpoint (returns JWT token)
    • GET /auth/me - Get current user information
    • POST /auth/logout - Logout endpoint (client-side token removal)
    • POST /auth/disable - Admin-only endpoint to disable authentication
  • User Management Routes (backend/app/api/routes/users.py)

    • GET /users - List all users (admin only)
    • POST /users - Create new user (admin only)
    • GET /users/{id} - Get user details (admin only)
    • PUT /users/{id} - Update user (admin only)
    • DELETE /users/{id} - Delete user (admin only)
  • Route Protection

    • Printer management routes (create, update, delete) protected with RequireAdminIfAuthEnabled
    • User management routes protected with RequireAdmin
    • Webhook routes updated to use API key authentication helpers

Frontend Changes

  • Authentication Context (frontend/src/contexts/AuthContext.tsx)

    • Global authentication state management
    • Login/logout functionality
    • Automatic redirect to setup page if authentication not configured
    • Token storage in localStorage
    • Auth status refresh functionality
  • New Pages

    • Setup Page (frontend/src/pages/SetupPage.tsx)
      • First-time authentication configuration
      • Option to enable/disable authentication
      • Admin user creation when enabling auth
      • Bambuddy-branded UI with logo
    • Login Page (frontend/src/pages/LoginPage.tsx)
      • User authentication form
      • Bambuddy-branded UI with logo
      • Error handling and validation
    • Users Page (frontend/src/pages/UsersPage.tsx)
      • User management interface (admin only)
      • Create, edit, and delete users
      • Role assignment (admin/user)
      • Styled with Bambuddy design system
  • Settings Page Updates

    • New "Users" tab in Settings
    • Authentication status display
    • Option to activate authentication (redirects to setup)
    • Link to user management page
    • Admin-only "Disable Authentication" button with confirmation modal
  • Layout & Navigation (frontend/src/components/Layout.tsx)

    • Settings tab hidden for users with 'user' role
    • Logout button visible in both collapsed and expanded sidebar states
    • Removed "Users" button from collapsed sidebar (accessible via Settings → Users tab)
  • Route Protection (frontend/src/App.tsx)

    • ProtectedRoute - Requires authentication when enabled
    • AdminRoute - Requires admin role (used for Settings page)
    • SetupRoute - Only accessible when authentication not enabled
    • Settings route protected with AdminRoute
  • API Client (frontend/src/api/client.ts)

    • Authentication token management (getAuthToken, setAuthToken)
    • Automatic token inclusion in API requests
    • New API functions:
      • getAuthStatus() - Check authentication status
      • setupAuth() - Configure authentication
      • login() - User login
      • logout() - User logout
      • getCurrentUser() - Get current user info
      • getUsers() - List users (admin)
      • createUser() - Create user (admin)
      • updateUser() - Update user (admin)
      • deleteUser() - Delete user (admin)
      • disableAuth() - Disable authentication (admin)

Security Features

  • Password Security

    • Passwords hashed using pbkdf2_sha256 (no length limitations)
    • Secure password storage (never stored in plaintext)
    • Minimum password length validation (6 characters)
  • Token Security

    • JWT tokens with 7-day expiration
    • Tokens stored in localStorage (can be enhanced with httpOnly cookies in future)
    • Automatic token validation on API requests
  • Role-Based Access Control

    • Admin role: Full access including printer settings and user management
    • User role: Limited access (print jobs, file management, filament management)
    • Settings page restricted to admin users only

Backward Compatibility

  • System works without authentication if not enabled
  • Existing installations continue to function normally
  • No breaking changes to existing functionality
  • Authentication can be enabled/disabled at any time

Screenshots

  • Setup page with Bambuddy branding
  • Login page with Bambuddy branding
  • Settings → Users tab showing authentication status
  • User management page with create/edit/delete functionality

Testing

  • I have tested this on my local machine
  • I have tested with my printer model:

Test Scenarios

  1. First-time Setup

    • Access setup page when authentication not configured
    • Enable authentication and create admin user
    • Disable authentication during setup
    • Prevent re-setup when already configured
  2. Authentication Flow

    • Login with valid credentials
    • Login with invalid credentials (error handling)
    • Logout functionality
    • Token persistence across page refreshes
    • Automatic redirect to login when token invalid
  3. Role-Based Access

    • Admin can access Settings page
    • User cannot access Settings page (redirected to home)
    • Settings tab hidden in sidebar for users with 'user' role
    • Admin can manage users
    • User cannot access user management
  4. User Management

    • Admin can create new users
    • Admin can edit user details (username, password, role)
    • Admin can delete users (except themselves)
    • Password validation (minimum 6 characters)
    • Username uniqueness validation
  5. Disable Authentication

    • Admin can disable authentication
    • All users deleted when authentication disabled
    • System returns to unauthenticated state
    • Redirect to setup page after disabling
  6. Backward Compatibility

    • System works without authentication enabled
    • All existing functionality preserved
    • No errors when authentication disabled

Checklist

  • My code follows the project's coding style
  • I have commented my code where necessary
  • I have updated the documentation (if needed)
  • My changes generate no new warnings
  • I have tested my changes thoroughly

Additional Notes

Technical Decisions

  1. Password Hashing: Chose pbkdf2_sha256 over bcrypt to avoid the 72-byte password length limitation. This ensures users can use long, complex passwords without truncation.

  2. JWT Tokens: Using JWT for stateless authentication. Tokens expire after 7 days and are automatically validated on each API request.

  3. Route Protection: Implemented flexible dependency system that allows routes to be protected only when authentication is enabled, maintaining backward compatibility.

  4. UI/UX: Applied Bambuddy branding to setup and login pages, ensuring consistent user experience. Used existing design system components (Card, Button, ConfirmModal) for user management interface.

Future Enhancements

  • Password reset functionality
  • Email verification (optional)
  • Two-factor authentication (2FA)
  • Session management (view active sessions, logout from all devices)
  • Password strength indicator
  • Account lockout after failed login attempts
  • Remember me functionality
  • HttpOnly cookies for token storage (more secure than localStorage)

Migration Notes

  • Existing installations will automatically create the users table on first run
  • No data migration required - system works without authentication by default
  • Administrators can enable authentication at any time via the setup page
  • When authentication is disabled, all user accounts are removed (can be re-enabled later)

🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/maziggy/bambuddy/pull/117 **Author:** [@JesseFPV](https://github.com/JesseFPV) **Created:** 1/21/2026 **Status:** ✅ Merged **Merged:** 1/21/2026 **Merged by:** [@maziggy](https://github.com/maziggy) **Base:** `main` ← **Head:** `main` --- ### 📝 Commits (5) - [`f8857ba`](https://github.com/maziggy/bambuddy/commit/f8857ba66643eb3ce97116dd90c0e75a9474f924) Added optional authentication and user management - [`3e1843f`](https://github.com/maziggy/bambuddy/commit/3e1843f834f226780058102981da6551fbea1729) Updated checks - [`d731cd2`](https://github.com/maziggy/bambuddy/commit/d731cd2a910f8ea25b39f50a0e7e6eb0ab30d0c9) Fixed lint errors - [`deeaabf`](https://github.com/maziggy/bambuddy/commit/deeaabfa8d7d0e4f0b6578b66e33dbf2ea191cb0) Fixed frontend lint test error - [`6e5cc55`](https://github.com/maziggy/bambuddy/commit/6e5cc551903a25e18271e93c157092384b4b6bf9) Fixed auth check and conftest ### 📊 Changes **30 files changed** (+10808 additions, -8775 deletions) <details> <summary>View changed files</summary> ➕ `backend/app/api/routes/auth.py` (+213 -0) 📝 `backend/app/api/routes/printers.py` (+4 -0) ➕ `backend/app/api/routes/users.py` (+205 -0) 📝 `backend/app/core/auth.py` (+306 -61) 📝 `backend/app/core/database.py` (+20 -0) 📝 `backend/app/main.py` (+4 -0) 📝 `backend/app/models/__init__.py` (+2 -0) ➕ `backend/app/models/user.py` (+20 -0) ➕ `backend/app/schemas/auth.py` (+47 -0) 📝 `backend/tests/conftest.py` (+1 -0) 📝 `frontend/package-lock.json` (+39 -14) 📝 `frontend/package.json` (+1 -0) 📝 `frontend/src/App.tsx` (+89 -23) 📝 `frontend/src/__tests__/components/Layout.test.tsx` (+3 -0) 📝 `frontend/src/__tests__/pages/SettingsPage.test.tsx` (+3 -0) 📝 `frontend/src/__tests__/utils.tsx` (+4 -1) 📝 `frontend/src/api/client.ts` (+121 -4) 📝 `frontend/src/components/Layout.tsx` (+33 -1) ➕ `frontend/src/contexts/AuthContext.tsx` (+116 -0) ➕ `frontend/src/pages/LoginPage.tsx` (+103 -0) _...and 10 more files_ </details> ### 📄 Description ## Description This PR adds a comprehensive authentication and authorization system to Bambuddy, allowing administrators to secure their instance with user authentication and role-based access control. The system is fully optional and maintains backward compatibility - existing installations without authentication will continue to work as before. ## Related Issue <!-- Link to the issue this PR addresses (if applicable) --> Fixes # ## Type of Change - [x] New feature (non-breaking change that adds functionality) - [ ] Bug fix (non-breaking change that fixes an issue) - [ ] Breaking change (fix or feature that would cause existing functionality to change) - [ ] Documentation update - [ ] Code refactoring - [ ] Performance improvement - [ ] Test addition or update ## Changes Made ### Backend Changes - **User Model & Database Migration** - Added `User` model with username, password hash, role, and active status - Database migration creates `users` table with proper indexes - Supports two roles: `admin` and `user` - **Authentication Core (`backend/app/core/auth.py`)** - Password hashing using `pbkdf2_sha256` (secure alternative to bcrypt without 72-byte limit) - JWT token generation and validation - FastAPI dependencies for authentication and authorization: - `get_current_user` - Requires valid JWT token - `get_current_active_user` - Requires active user account - `require_auth_if_enabled` - Optional auth when enabled - `require_role(role)` - Role-based access control - `RequireAdmin()` - Admin-only dependency - `RequireAdminIfAuthEnabled()` - Admin-only when auth is enabled - API key authentication helpers (`get_api_key`, `check_permission`, `check_printer_access`) - **Authentication Routes (`backend/app/api/routes/auth.py`)** - `POST /auth/setup` - First-time setup to enable/disable authentication and create admin user - `GET /auth/status` - Public endpoint to check authentication status - `POST /auth/login` - User login endpoint (returns JWT token) - `GET /auth/me` - Get current user information - `POST /auth/logout` - Logout endpoint (client-side token removal) - `POST /auth/disable` - Admin-only endpoint to disable authentication - **User Management Routes (`backend/app/api/routes/users.py`)** - `GET /users` - List all users (admin only) - `POST /users` - Create new user (admin only) - `GET /users/{id}` - Get user details (admin only) - `PUT /users/{id}` - Update user (admin only) - `DELETE /users/{id}` - Delete user (admin only) - **Route Protection** - Printer management routes (create, update, delete) protected with `RequireAdminIfAuthEnabled` - User management routes protected with `RequireAdmin` - Webhook routes updated to use API key authentication helpers ### Frontend Changes - **Authentication Context (`frontend/src/contexts/AuthContext.tsx`)** - Global authentication state management - Login/logout functionality - Automatic redirect to setup page if authentication not configured - Token storage in localStorage - Auth status refresh functionality - **New Pages** - **Setup Page** (`frontend/src/pages/SetupPage.tsx`) - First-time authentication configuration - Option to enable/disable authentication - Admin user creation when enabling auth - Bambuddy-branded UI with logo - **Login Page** (`frontend/src/pages/LoginPage.tsx`) - User authentication form - Bambuddy-branded UI with logo - Error handling and validation - **Users Page** (`frontend/src/pages/UsersPage.tsx`) - User management interface (admin only) - Create, edit, and delete users - Role assignment (admin/user) - Styled with Bambuddy design system - **Settings Page Updates** - New "Users" tab in Settings - Authentication status display - Option to activate authentication (redirects to setup) - Link to user management page - Admin-only "Disable Authentication" button with confirmation modal - **Layout & Navigation (`frontend/src/components/Layout.tsx`)** - Settings tab hidden for users with 'user' role - Logout button visible in both collapsed and expanded sidebar states - Removed "Users" button from collapsed sidebar (accessible via Settings → Users tab) - **Route Protection (`frontend/src/App.tsx`)** - `ProtectedRoute` - Requires authentication when enabled - `AdminRoute` - Requires admin role (used for Settings page) - `SetupRoute` - Only accessible when authentication not enabled - Settings route protected with `AdminRoute` - **API Client (`frontend/src/api/client.ts`)** - Authentication token management (`getAuthToken`, `setAuthToken`) - Automatic token inclusion in API requests - New API functions: - `getAuthStatus()` - Check authentication status - `setupAuth()` - Configure authentication - `login()` - User login - `logout()` - User logout - `getCurrentUser()` - Get current user info - `getUsers()` - List users (admin) - `createUser()` - Create user (admin) - `updateUser()` - Update user (admin) - `deleteUser()` - Delete user (admin) - `disableAuth()` - Disable authentication (admin) ### Security Features - **Password Security** - Passwords hashed using `pbkdf2_sha256` (no length limitations) - Secure password storage (never stored in plaintext) - Minimum password length validation (6 characters) - **Token Security** - JWT tokens with 7-day expiration - Tokens stored in localStorage (can be enhanced with httpOnly cookies in future) - Automatic token validation on API requests - **Role-Based Access Control** - Admin role: Full access including printer settings and user management - User role: Limited access (print jobs, file management, filament management) - Settings page restricted to admin users only ### Backward Compatibility - System works without authentication if not enabled - Existing installations continue to function normally - No breaking changes to existing functionality - Authentication can be enabled/disabled at any time ## Screenshots <!-- Add screenshots here if available --> - Setup page with Bambuddy branding - Login page with Bambuddy branding - Settings → Users tab showing authentication status - User management page with create/edit/delete functionality ## Testing - [x] I have tested this on my local machine - [x] I have tested with my printer model: <!-- e.g., X1C, P1S, A1 --> ### Test Scenarios 1. **First-time Setup** - ✅ Access setup page when authentication not configured - ✅ Enable authentication and create admin user - ✅ Disable authentication during setup - ✅ Prevent re-setup when already configured 2. **Authentication Flow** - ✅ Login with valid credentials - ✅ Login with invalid credentials (error handling) - ✅ Logout functionality - ✅ Token persistence across page refreshes - ✅ Automatic redirect to login when token invalid 3. **Role-Based Access** - ✅ Admin can access Settings page - ✅ User cannot access Settings page (redirected to home) - ✅ Settings tab hidden in sidebar for users with 'user' role - ✅ Admin can manage users - ✅ User cannot access user management 4. **User Management** - ✅ Admin can create new users - ✅ Admin can edit user details (username, password, role) - ✅ Admin can delete users (except themselves) - ✅ Password validation (minimum 6 characters) - ✅ Username uniqueness validation 5. **Disable Authentication** - ✅ Admin can disable authentication - ✅ All users deleted when authentication disabled - ✅ System returns to unauthenticated state - ✅ Redirect to setup page after disabling 6. **Backward Compatibility** - ✅ System works without authentication enabled - ✅ All existing functionality preserved - ✅ No errors when authentication disabled ## Checklist - [x] My code follows the project's coding style - [x] I have commented my code where necessary - [ ] I have updated the documentation (if needed) - [x] My changes generate no new warnings - [x] I have tested my changes thoroughly ## Additional Notes ### Technical Decisions 1. **Password Hashing**: Chose `pbkdf2_sha256` over `bcrypt` to avoid the 72-byte password length limitation. This ensures users can use long, complex passwords without truncation. 2. **JWT Tokens**: Using JWT for stateless authentication. Tokens expire after 7 days and are automatically validated on each API request. 3. **Route Protection**: Implemented flexible dependency system that allows routes to be protected only when authentication is enabled, maintaining backward compatibility. 4. **UI/UX**: Applied Bambuddy branding to setup and login pages, ensuring consistent user experience. Used existing design system components (Card, Button, ConfirmModal) for user management interface. ### Future Enhancements - [ ] Password reset functionality - [ ] Email verification (optional) - [ ] Two-factor authentication (2FA) - [ ] Session management (view active sessions, logout from all devices) - [ ] Password strength indicator - [ ] Account lockout after failed login attempts - [ ] Remember me functionality - [ ] HttpOnly cookies for token storage (more secure than localStorage) ### Migration Notes - Existing installations will automatically create the `users` table on first run - No data migration required - system works without authentication by default - Administrators can enable authentication at any time via the setup page - When authentication is disabled, all user accounts are removed (can be re-enabled later) --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
BreizhHardware 2026-05-06 12:34:01 +02:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/bambuddy#931
No description provided.